ActivityManagerService.java revision da0d07be7bc274e06797d6b943483df7b3d6625c
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_OOM_ADJ;
82import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
83import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
84import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
85import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
86import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
87import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
88import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
89import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
90import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
91import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
92import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
93import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
94import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
95import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
96import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
97import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
98import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
99import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
100import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
101import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
102import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
103import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
104import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
105import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
106import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
107import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
108import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
109import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
110import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
111import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
112import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
113import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
114import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
115import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
116import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
117import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
118import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
119import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
120import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
121import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
122import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
123import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
124import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
125import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
126import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
127import static com.android.server.am.ActivityStackSupervisor.CREATE_IF_NEEDED;
128import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
129import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
130import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
131import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
132import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
133import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
134import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
135import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
136import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
137import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
138import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
139import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
140import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
141import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
142import static com.android.server.wm.AppTransition.TRANSIT_NONE;
143import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
144import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
145import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
146import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
147import static org.xmlpull.v1.XmlPullParser.START_TAG;
148
149import static java.lang.Integer.MAX_VALUE;
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.VrManagerInternal;
371import com.android.server.wm.WindowManagerService;
372
373import org.xmlpull.v1.XmlPullParser;
374import org.xmlpull.v1.XmlPullParserException;
375import org.xmlpull.v1.XmlSerializer;
376
377import java.io.File;
378import java.io.FileDescriptor;
379import java.io.FileInputStream;
380import java.io.FileNotFoundException;
381import java.io.FileOutputStream;
382import java.io.IOException;
383import java.io.InputStreamReader;
384import java.io.PrintWriter;
385import java.io.StringWriter;
386import java.lang.ref.WeakReference;
387import java.nio.charset.StandardCharsets;
388import java.util.ArrayList;
389import java.util.Arrays;
390import java.util.Collections;
391import java.util.Comparator;
392import java.util.HashMap;
393import java.util.HashSet;
394import java.util.Iterator;
395import java.util.List;
396import java.util.Locale;
397import java.util.Map;
398import java.util.Objects;
399import java.util.Set;
400import java.util.concurrent.CountDownLatch;
401import java.util.concurrent.atomic.AtomicBoolean;
402import java.util.concurrent.atomic.AtomicLong;
403
404import dalvik.system.VMRuntime;
405
406import libcore.io.IoUtils;
407import libcore.util.EmptyArray;
408
409public class ActivityManagerService extends IActivityManager.Stub
410        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
411
412    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
413    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
414    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
415    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
416    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
417    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
418    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
419    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
420    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
421    private static final String TAG_LRU = TAG + POSTFIX_LRU;
422    private static final String TAG_MU = TAG + POSTFIX_MU;
423    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
424    private static final String TAG_POWER = TAG + POSTFIX_POWER;
425    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
426    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
427    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
428    private static final String TAG_PSS = TAG + POSTFIX_PSS;
429    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
430    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
431    private static final String TAG_STACK = TAG + POSTFIX_STACK;
432    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
433    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
434    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
435    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
436    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
437
438    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
439    // here so that while the job scheduler can depend on AMS, the other way around
440    // need not be the case.
441    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
442
443    /** Control over CPU and battery monitoring */
444    // write battery stats every 30 minutes.
445    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
446    static final boolean MONITOR_CPU_USAGE = true;
447    // don't sample cpu less than every 5 seconds.
448    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
449    // wait possibly forever for next cpu sample.
450    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
451    static final boolean MONITOR_THREAD_CPU_USAGE = false;
452
453    // The flags that are set for all calls we make to the package manager.
454    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
455
456    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
457
458    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
459
460    // Amount of time after a call to stopAppSwitches() during which we will
461    // prevent further untrusted switches from happening.
462    static final long APP_SWITCH_DELAY_TIME = 5*1000;
463
464    // How long we wait for a launched process to attach to the activity manager
465    // before we decide it's never going to come up for real.
466    static final int PROC_START_TIMEOUT = 10*1000;
467    // How long we wait for an attached process to publish its content providers
468    // before we decide it must be hung.
469    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
470
471    // How long we will retain processes hosting content providers in the "last activity"
472    // state before allowing them to drop down to the regular cached LRU list.  This is
473    // to avoid thrashing of provider processes under low memory situations.
474    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
475
476    // How long we wait for a launched process to attach to the activity manager
477    // before we decide it's never going to come up for real, when the process was
478    // started with a wrapper for instrumentation (such as Valgrind) because it
479    // could take much longer than usual.
480    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
481
482    // How long to wait after going idle before forcing apps to GC.
483    static final int GC_TIMEOUT = 5*1000;
484
485    // The minimum amount of time between successive GC requests for a process.
486    static final int GC_MIN_INTERVAL = 60*1000;
487
488    // The minimum amount of time between successive PSS requests for a process.
489    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
490
491    // The minimum amount of time between successive PSS requests for a process
492    // when the request is due to the memory state being lowered.
493    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
494
495    // The rate at which we check for apps using excessive power -- 15 mins.
496    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
497
498    // The minimum sample duration we will allow before deciding we have
499    // enough data on wake locks to start killing things.
500    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
501
502    // The minimum sample duration we will allow before deciding we have
503    // enough data on CPU usage to start killing things.
504    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
505
506    // How long we allow a receiver to run before giving up on it.
507    static final int BROADCAST_FG_TIMEOUT = 10*1000;
508    static final int BROADCAST_BG_TIMEOUT = 60*1000;
509
510    // How long we wait until we timeout on key dispatching.
511    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
512
513    // How long we wait until we timeout on key dispatching during instrumentation.
514    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
515
516    // This is the amount of time an app needs to be running a foreground service before
517    // we will consider it to be doing interaction for usage stats.
518    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
519
520    // Maximum amount of time we will allow to elapse before re-reporting usage stats
521    // interaction with foreground processes.
522    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
523
524    // This is the amount of time we allow an app to settle after it goes into the background,
525    // before we start restricting what it can do.
526    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
527
528    // How long to wait in getAssistContextExtras for the activity and foreground services
529    // to respond with the result.
530    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
531
532    // How long top wait when going through the modern assist (which doesn't need to block
533    // on getting this result before starting to launch its UI).
534    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
535
536    // How long to wait in getAutoFillAssistStructure() for the activity to respond with the result.
537    static final int PENDING_AUTO_FILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
538
539    // Maximum number of persisted Uri grants a package is allowed
540    static final int MAX_PERSISTED_URI_GRANTS = 128;
541
542    static final int MY_PID = Process.myPid();
543
544    static final String[] EMPTY_STRING_ARRAY = new String[0];
545
546    // How many bytes to write into the dropbox log before truncating
547    static final int DROPBOX_MAX_SIZE = 192 * 1024;
548    // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
549    // as one line, but close enough for now.
550    static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
551
552    // Access modes for handleIncomingUser.
553    static final int ALLOW_NON_FULL = 0;
554    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
555    static final int ALLOW_FULL_ONLY = 2;
556
557    // Necessary ApplicationInfo flags to mark an app as persistent
558    private static final int PERSISTENT_MASK =
559            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
560
561    // Intent sent when remote bugreport collection has been completed
562    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
563            "com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED";
564
565    // Used to indicate that an app transition should be animated.
566    static final boolean ANIMATE = true;
567
568    // Determines whether to take full screen screenshots
569    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
570
571    /** All system services */
572    SystemServiceManager mSystemServiceManager;
573    AssistUtils mAssistUtils;
574
575    private Installer mInstaller;
576
577    /** Run all ActivityStacks through this */
578    final ActivityStackSupervisor mStackSupervisor;
579    private final KeyguardController mKeyguardController;
580
581    final ActivityStarter mActivityStarter;
582
583    final TaskChangeNotificationController mTaskChangeNotificationController;
584
585    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
586
587    final ArrayList<ActiveInstrumentation> mActiveInstrumentation = new ArrayList<>();
588
589    public final IntentFirewall mIntentFirewall;
590
591    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
592    // default action automatically.  Important for devices without direct input
593    // devices.
594    private boolean mShowDialogs = true;
595    private boolean mInVrMode = false;
596
597    // Whether we should use SCHED_FIFO for UI and RenderThreads.
598    private boolean mUseFifoUiScheduling = false;
599
600    BroadcastQueue mFgBroadcastQueue;
601    BroadcastQueue mBgBroadcastQueue;
602    // Convenient for easy iteration over the queues. Foreground is first
603    // so that dispatch of foreground broadcasts gets precedence.
604    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
605
606    BroadcastStats mLastBroadcastStats;
607    BroadcastStats mCurBroadcastStats;
608
609    BroadcastQueue broadcastQueueForIntent(Intent intent) {
610        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
611        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
612                "Broadcast intent " + intent + " on "
613                + (isFg ? "foreground" : "background") + " queue");
614        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
615    }
616
617    /**
618     * The last resumed activity. This is identical to the current resumed activity most
619     * of the time but could be different when we're pausing one activity before we resume
620     * another activity.
621     */
622    private ActivityRecord mLastResumedActivity;
623
624    /**
625     * If non-null, we are tracking the time the user spends in the currently focused app.
626     */
627    private AppTimeTracker mCurAppTimeTracker;
628
629    /**
630     * List of intents that were used to start the most recent tasks.
631     */
632    final RecentTasks mRecentTasks;
633
634    /**
635     * For addAppTask: cached of the last activity component that was added.
636     */
637    ComponentName mLastAddedTaskComponent;
638
639    /**
640     * For addAppTask: cached of the last activity uid that was added.
641     */
642    int mLastAddedTaskUid;
643
644    /**
645     * For addAppTask: cached of the last ActivityInfo that was added.
646     */
647    ActivityInfo mLastAddedTaskActivity;
648
649    /**
650     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
651     */
652    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
653
654    /**
655     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
656     */
657    String mDeviceOwnerName;
658
659    final UserController mUserController;
660
661    final AppErrors mAppErrors;
662
663    public boolean canShowErrorDialogs() {
664        return mShowDialogs && !mSleeping && !mShuttingDown
665                && !mKeyguardController.isKeyguardShowing();
666    }
667
668    private static final class PriorityState {
669        // Acts as counter for number of synchronized region that needs to acquire 'this' as a lock
670        // the current thread is currently in. When it drops down to zero, we will no longer boost
671        // the thread's priority.
672        private int regionCounter = 0;
673
674        // The thread's previous priority before boosting.
675        private int prevPriority = Integer.MIN_VALUE;
676    }
677
678    static ThreadLocal<PriorityState> sThreadPriorityState = new ThreadLocal<PriorityState>() {
679        @Override protected PriorityState initialValue() {
680            return new PriorityState();
681        }
682    };
683
684    static void boostPriorityForLockedSection() {
685        int tid = Process.myTid();
686        int prevPriority = Process.getThreadPriority(tid);
687        PriorityState state = sThreadPriorityState.get();
688        if (state.regionCounter == 0 && prevPriority > -2) {
689            state.prevPriority = prevPriority;
690            Process.setThreadPriority(tid, -2);
691        }
692        state.regionCounter++;
693    }
694
695    static void resetPriorityAfterLockedSection() {
696        PriorityState state = sThreadPriorityState.get();
697        state.regionCounter--;
698        if (state.regionCounter == 0 && state.prevPriority > -2) {
699            Process.setThreadPriority(Process.myTid(), state.prevPriority);
700        }
701    }
702
703    public class PendingAssistExtras extends Binder implements Runnable {
704        public final ActivityRecord activity;
705        public final Bundle extras;
706        public final Intent intent;
707        public final String hint;
708        public final IResultReceiver receiver;
709        public final int userHandle;
710        public boolean haveResult = false;
711        public Bundle result = null;
712        public AssistStructure structure = null;
713        public AssistContent content = null;
714        public Bundle receiverExtras;
715
716        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
717                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
718            activity = _activity;
719            extras = _extras;
720            intent = _intent;
721            hint = _hint;
722            receiver = _receiver;
723            receiverExtras = _receiverExtras;
724            userHandle = _userHandle;
725        }
726        @Override
727        public void run() {
728            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
729            synchronized (this) {
730                haveResult = true;
731                notifyAll();
732            }
733            pendingAssistExtrasTimedOut(this);
734        }
735    }
736
737    final ArrayList<PendingAssistExtras> mPendingAssistExtras
738            = new ArrayList<PendingAssistExtras>();
739
740    /**
741     * Process management.
742     */
743    final ProcessList mProcessList = new ProcessList();
744
745    /**
746     * All of the applications we currently have running organized by name.
747     * The keys are strings of the application package name (as
748     * returned by the package manager), and the keys are ApplicationRecord
749     * objects.
750     */
751    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
752
753    /**
754     * Tracking long-term execution of processes to look for abuse and other
755     * bad app behavior.
756     */
757    final ProcessStatsService mProcessStats;
758
759    /**
760     * The currently running isolated processes.
761     */
762    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
763
764    /**
765     * Counter for assigning isolated process uids, to avoid frequently reusing the
766     * same ones.
767     */
768    int mNextIsolatedProcessUid = 0;
769
770    /**
771     * The currently running heavy-weight process, if any.
772     */
773    ProcessRecord mHeavyWeightProcess = null;
774
775    /**
776     * Non-persistent app uid whitelist for background restrictions
777     */
778    int[] mBackgroundUidWhitelist = new int[] {
779            Process.BLUETOOTH_UID
780    };
781
782    /**
783     * Broadcast actions that will always be deliverable to unlaunched/background apps
784     */
785    ArraySet<String> mBackgroundLaunchBroadcasts;
786
787    /**
788     * All of the processes we currently have running organized by pid.
789     * The keys are the pid running the application.
790     *
791     * <p>NOTE: This object is protected by its own lock, NOT the global
792     * activity manager lock!
793     */
794    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
795
796    /**
797     * All of the processes that have been forced to be foreground.  The key
798     * is the pid of the caller who requested it (we hold a death
799     * link on it).
800     */
801    abstract class ForegroundToken implements IBinder.DeathRecipient {
802        int pid;
803        IBinder token;
804    }
805    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
806
807    /**
808     * List of records for processes that someone had tried to start before the
809     * system was ready.  We don't start them at that point, but ensure they
810     * are started by the time booting is complete.
811     */
812    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
813
814    /**
815     * List of persistent applications that are in the process
816     * of being started.
817     */
818    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
819
820    /**
821     * Processes that are being forcibly torn down.
822     */
823    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
824
825    /**
826     * List of running applications, sorted by recent usage.
827     * The first entry in the list is the least recently used.
828     */
829    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
830
831    /**
832     * Where in mLruProcesses that the processes hosting activities start.
833     */
834    int mLruProcessActivityStart = 0;
835
836    /**
837     * Where in mLruProcesses that the processes hosting services start.
838     * This is after (lower index) than mLruProcessesActivityStart.
839     */
840    int mLruProcessServiceStart = 0;
841
842    /**
843     * List of processes that should gc as soon as things are idle.
844     */
845    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
846
847    /**
848     * Processes we want to collect PSS data from.
849     */
850    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
851
852    private boolean mBinderTransactionTrackingEnabled = false;
853
854    /**
855     * Last time we requested PSS data of all processes.
856     */
857    long mLastFullPssTime = SystemClock.uptimeMillis();
858
859    /**
860     * If set, the next time we collect PSS data we should do a full collection
861     * with data from native processes and the kernel.
862     */
863    boolean mFullPssPending = false;
864
865    /**
866     * This is the process holding what we currently consider to be
867     * the "home" activity.
868     */
869    ProcessRecord mHomeProcess;
870
871    /**
872     * This is the process holding the activity the user last visited that
873     * is in a different process from the one they are currently in.
874     */
875    ProcessRecord mPreviousProcess;
876
877    /**
878     * The time at which the previous process was last visible.
879     */
880    long mPreviousProcessVisibleTime;
881
882    /**
883     * Track all uids that have actively running processes.
884     */
885    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
886
887    /**
888     * This is for verifying the UID report flow.
889     */
890    static final boolean VALIDATE_UID_STATES = true;
891    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
892
893    /**
894     * Packages that the user has asked to have run in screen size
895     * compatibility mode instead of filling the screen.
896     */
897    final CompatModePackages mCompatModePackages;
898
899    /**
900     * Set of IntentSenderRecord objects that are currently active.
901     */
902    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
903            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
904
905    /**
906     * Fingerprints (hashCode()) of stack traces that we've
907     * already logged DropBox entries for.  Guarded by itself.  If
908     * something (rogue user app) forces this over
909     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
910     */
911    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
912    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
913
914    /**
915     * Strict Mode background batched logging state.
916     *
917     * The string buffer is guarded by itself, and its lock is also
918     * used to determine if another batched write is already
919     * in-flight.
920     */
921    private final StringBuilder mStrictModeBuffer = new StringBuilder();
922
923    /**
924     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
925     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
926     */
927    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
928
929    /**
930     * Resolver for broadcast intents to registered receivers.
931     * Holds BroadcastFilter (subclass of IntentFilter).
932     */
933    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
934            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
935        @Override
936        protected boolean allowFilterResult(
937                BroadcastFilter filter, List<BroadcastFilter> dest) {
938            IBinder target = filter.receiverList.receiver.asBinder();
939            for (int i = dest.size() - 1; i >= 0; i--) {
940                if (dest.get(i).receiverList.receiver.asBinder() == target) {
941                    return false;
942                }
943            }
944            return true;
945        }
946
947        @Override
948        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
949            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
950                    || userId == filter.owningUserId) {
951                return super.newResult(filter, match, userId);
952            }
953            return null;
954        }
955
956        @Override
957        protected BroadcastFilter[] newArray(int size) {
958            return new BroadcastFilter[size];
959        }
960
961        @Override
962        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
963            return packageName.equals(filter.packageName);
964        }
965    };
966
967    /**
968     * State of all active sticky broadcasts per user.  Keys are the action of the
969     * sticky Intent, values are an ArrayList of all broadcasted intents with
970     * that action (which should usually be one).  The SparseArray is keyed
971     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
972     * for stickies that are sent to all users.
973     */
974    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
975            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
976
977    final ActiveServices mServices;
978
979    final static class Association {
980        final int mSourceUid;
981        final String mSourceProcess;
982        final int mTargetUid;
983        final ComponentName mTargetComponent;
984        final String mTargetProcess;
985
986        int mCount;
987        long mTime;
988
989        int mNesting;
990        long mStartTime;
991
992        // states of the source process when the bind occurred.
993        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
994        long mLastStateUptime;
995        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
996                - ActivityManager.MIN_PROCESS_STATE+1];
997
998        Association(int sourceUid, String sourceProcess, int targetUid,
999                ComponentName targetComponent, String targetProcess) {
1000            mSourceUid = sourceUid;
1001            mSourceProcess = sourceProcess;
1002            mTargetUid = targetUid;
1003            mTargetComponent = targetComponent;
1004            mTargetProcess = targetProcess;
1005        }
1006    }
1007
1008    /**
1009     * When service association tracking is enabled, this is all of the associations we
1010     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
1011     * -> association data.
1012     */
1013    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
1014            mAssociations = new SparseArray<>();
1015    boolean mTrackingAssociations;
1016
1017    /**
1018     * Backup/restore process management
1019     */
1020    String mBackupAppName = null;
1021    BackupRecord mBackupTarget = null;
1022
1023    final ProviderMap mProviderMap;
1024
1025    /**
1026     * List of content providers who have clients waiting for them.  The
1027     * application is currently being launched and the provider will be
1028     * removed from this list once it is published.
1029     */
1030    final ArrayList<ContentProviderRecord> mLaunchingProviders
1031            = new ArrayList<ContentProviderRecord>();
1032
1033    /**
1034     * File storing persisted {@link #mGrantedUriPermissions}.
1035     */
1036    private final AtomicFile mGrantFile;
1037
1038    /** XML constants used in {@link #mGrantFile} */
1039    private static final String TAG_URI_GRANTS = "uri-grants";
1040    private static final String TAG_URI_GRANT = "uri-grant";
1041    private static final String ATTR_USER_HANDLE = "userHandle";
1042    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1043    private static final String ATTR_TARGET_USER_ID = "targetUserId";
1044    private static final String ATTR_SOURCE_PKG = "sourcePkg";
1045    private static final String ATTR_TARGET_PKG = "targetPkg";
1046    private static final String ATTR_URI = "uri";
1047    private static final String ATTR_MODE_FLAGS = "modeFlags";
1048    private static final String ATTR_CREATED_TIME = "createdTime";
1049    private static final String ATTR_PREFIX = "prefix";
1050
1051    /**
1052     * Global set of specific {@link Uri} permissions that have been granted.
1053     * This optimized lookup structure maps from {@link UriPermission#targetUid}
1054     * to {@link UriPermission#uri} to {@link UriPermission}.
1055     */
1056    @GuardedBy("this")
1057    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1058            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1059
1060    public static class GrantUri {
1061        public final int sourceUserId;
1062        public final Uri uri;
1063        public boolean prefix;
1064
1065        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1066            this.sourceUserId = sourceUserId;
1067            this.uri = uri;
1068            this.prefix = prefix;
1069        }
1070
1071        @Override
1072        public int hashCode() {
1073            int hashCode = 1;
1074            hashCode = 31 * hashCode + sourceUserId;
1075            hashCode = 31 * hashCode + uri.hashCode();
1076            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1077            return hashCode;
1078        }
1079
1080        @Override
1081        public boolean equals(Object o) {
1082            if (o instanceof GrantUri) {
1083                GrantUri other = (GrantUri) o;
1084                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1085                        && prefix == other.prefix;
1086            }
1087            return false;
1088        }
1089
1090        @Override
1091        public String toString() {
1092            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1093            if (prefix) result += " [prefix]";
1094            return result;
1095        }
1096
1097        public String toSafeString() {
1098            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1099            if (prefix) result += " [prefix]";
1100            return result;
1101        }
1102
1103        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1104            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1105                    ContentProvider.getUriWithoutUserId(uri), false);
1106        }
1107    }
1108
1109    CoreSettingsObserver mCoreSettingsObserver;
1110
1111    FontScaleSettingObserver mFontScaleSettingObserver;
1112
1113    private final class FontScaleSettingObserver extends ContentObserver {
1114        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1115
1116        public FontScaleSettingObserver() {
1117            super(mHandler);
1118            ContentResolver resolver = mContext.getContentResolver();
1119            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1120        }
1121
1122        @Override
1123        public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1124            if (mFontScaleUri.equals(uri)) {
1125                updateFontScaleIfNeeded(userId);
1126            }
1127        }
1128    }
1129
1130    /**
1131     * Thread-local storage used to carry caller permissions over through
1132     * indirect content-provider access.
1133     */
1134    private class Identity {
1135        public final IBinder token;
1136        public final int pid;
1137        public final int uid;
1138
1139        Identity(IBinder _token, int _pid, int _uid) {
1140            token = _token;
1141            pid = _pid;
1142            uid = _uid;
1143        }
1144    }
1145
1146    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1147
1148    /**
1149     * All information we have collected about the runtime performance of
1150     * any user id that can impact battery performance.
1151     */
1152    final BatteryStatsService mBatteryStatsService;
1153
1154    /**
1155     * Information about component usage
1156     */
1157    UsageStatsManagerInternal mUsageStatsService;
1158
1159    /**
1160     * Access to DeviceIdleController service.
1161     */
1162    DeviceIdleController.LocalService mLocalDeviceIdleController;
1163
1164    /**
1165     * Set of app ids that are whitelisted for device idle and thus background check.
1166     */
1167    int[] mDeviceIdleWhitelist = new int[0];
1168
1169    /**
1170     * Set of app ids that are temporarily allowed to escape bg check due to high-pri message
1171     */
1172    int[] mDeviceIdleTempWhitelist = new int[0];
1173
1174    /**
1175     * Information about and control over application operations
1176     */
1177    final AppOpsService mAppOpsService;
1178
1179    /** Current sequencing integer of the configuration, for skipping old configurations. */
1180    private int mConfigurationSeq;
1181
1182    /**
1183     * Temp object used when global and/or display override configuration is updated. It is also
1184     * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
1185     * anyone...
1186     */
1187    private Configuration mTempConfig = new Configuration();
1188
1189    private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
1190            new UpdateConfigurationResult();
1191    private static final class UpdateConfigurationResult {
1192        // Configuration changes that were updated.
1193        int changes;
1194        // If the activity was relaunched to match the new configuration.
1195        boolean activityRelaunched;
1196
1197        void reset() {
1198            changes = 0;
1199            activityRelaunched = false;
1200        }
1201    }
1202
1203    boolean mSuppressResizeConfigChanges;
1204
1205    /**
1206     * Hardware-reported OpenGLES version.
1207     */
1208    final int GL_ES_VERSION;
1209
1210    /**
1211     * List of initialization arguments to pass to all processes when binding applications to them.
1212     * For example, references to the commonly used services.
1213     */
1214    HashMap<String, IBinder> mAppBindArgs;
1215    HashMap<String, IBinder> mIsolatedAppBindArgs;
1216
1217    /**
1218     * Temporary to avoid allocations.  Protected by main lock.
1219     */
1220    final StringBuilder mStringBuilder = new StringBuilder(256);
1221
1222    /**
1223     * Used to control how we initialize the service.
1224     */
1225    ComponentName mTopComponent;
1226    String mTopAction = Intent.ACTION_MAIN;
1227    String mTopData;
1228
1229    volatile boolean mProcessesReady = false;
1230    volatile boolean mSystemReady = false;
1231    volatile boolean mOnBattery = false;
1232    volatile int mFactoryTest;
1233
1234    @GuardedBy("this") boolean mBooting = false;
1235    @GuardedBy("this") boolean mCallFinishBooting = false;
1236    @GuardedBy("this") boolean mBootAnimationComplete = false;
1237    @GuardedBy("this") boolean mLaunchWarningShown = false;
1238    @GuardedBy("this") boolean mCheckedForSetup = false;
1239
1240    Context mContext;
1241
1242    /**
1243     * The time at which we will allow normal application switches again,
1244     * after a call to {@link #stopAppSwitches()}.
1245     */
1246    long mAppSwitchesAllowedTime;
1247
1248    /**
1249     * This is set to true after the first switch after mAppSwitchesAllowedTime
1250     * is set; any switches after that will clear the time.
1251     */
1252    boolean mDidAppSwitch;
1253
1254    /**
1255     * Last time (in realtime) at which we checked for power usage.
1256     */
1257    long mLastPowerCheckRealtime;
1258
1259    /**
1260     * Last time (in uptime) at which we checked for power usage.
1261     */
1262    long mLastPowerCheckUptime;
1263
1264    /**
1265     * Set while we are wanting to sleep, to prevent any
1266     * activities from being started/resumed.
1267     *
1268     * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
1269     *
1270     * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
1271     * while in the sleep state until there is a pending transition out of sleep, in which case
1272     * mSleeping is set to false, and remains false while awake.
1273     *
1274     * Whether mSleeping can quickly toggled between true/false without the device actually
1275     * display changing states is undefined.
1276     */
1277    private boolean mSleeping = false;
1278
1279    /**
1280     * The process state used for processes that are running the top activities.
1281     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1282     */
1283    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1284
1285    /**
1286     * Set while we are running a voice interaction.  This overrides
1287     * sleeping while it is active.
1288     */
1289    private IVoiceInteractionSession mRunningVoice;
1290
1291    /**
1292     * For some direct access we need to power manager.
1293     */
1294    PowerManagerInternal mLocalPowerManager;
1295
1296    /**
1297     * We want to hold a wake lock while running a voice interaction session, since
1298     * this may happen with the screen off and we need to keep the CPU running to
1299     * be able to continue to interact with the user.
1300     */
1301    PowerManager.WakeLock mVoiceWakeLock;
1302
1303    /**
1304     * State of external calls telling us if the device is awake or asleep.
1305     */
1306    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1307
1308    /**
1309     * A list of tokens that cause the top activity to be put to sleep.
1310     * They are used by components that may hide and block interaction with underlying
1311     * activities.
1312     */
1313    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1314
1315    /**
1316     * Set if we are shutting down the system, similar to sleeping.
1317     */
1318    boolean mShuttingDown = false;
1319
1320    /**
1321     * Current sequence id for oom_adj computation traversal.
1322     */
1323    int mAdjSeq = 0;
1324
1325    /**
1326     * Current sequence id for process LRU updating.
1327     */
1328    int mLruSeq = 0;
1329
1330    /**
1331     * Keep track of the non-cached/empty process we last found, to help
1332     * determine how to distribute cached/empty processes next time.
1333     */
1334    int mNumNonCachedProcs = 0;
1335
1336    /**
1337     * Keep track of the number of cached hidden procs, to balance oom adj
1338     * distribution between those and empty procs.
1339     */
1340    int mNumCachedHiddenProcs = 0;
1341
1342    /**
1343     * Keep track of the number of service processes we last found, to
1344     * determine on the next iteration which should be B services.
1345     */
1346    int mNumServiceProcs = 0;
1347    int mNewNumAServiceProcs = 0;
1348    int mNewNumServiceProcs = 0;
1349
1350    /**
1351     * Allow the current computed overall memory level of the system to go down?
1352     * This is set to false when we are killing processes for reasons other than
1353     * memory management, so that the now smaller process list will not be taken as
1354     * an indication that memory is tighter.
1355     */
1356    boolean mAllowLowerMemLevel = false;
1357
1358    /**
1359     * The last computed memory level, for holding when we are in a state that
1360     * processes are going away for other reasons.
1361     */
1362    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1363
1364    /**
1365     * The last total number of process we have, to determine if changes actually look
1366     * like a shrinking number of process due to lower RAM.
1367     */
1368    int mLastNumProcesses;
1369
1370    /**
1371     * The uptime of the last time we performed idle maintenance.
1372     */
1373    long mLastIdleTime = SystemClock.uptimeMillis();
1374
1375    /**
1376     * Total time spent with RAM that has been added in the past since the last idle time.
1377     */
1378    long mLowRamTimeSinceLastIdle = 0;
1379
1380    /**
1381     * If RAM is currently low, when that horrible situation started.
1382     */
1383    long mLowRamStartTime = 0;
1384
1385    /**
1386     * For reporting to battery stats the current top application.
1387     */
1388    private String mCurResumedPackage = null;
1389    private int mCurResumedUid = -1;
1390
1391    /**
1392     * For reporting to battery stats the apps currently running foreground
1393     * service.  The ProcessMap is package/uid tuples; each of these contain
1394     * an array of the currently foreground processes.
1395     */
1396    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1397            = new ProcessMap<ArrayList<ProcessRecord>>();
1398
1399    /**
1400     * This is set if we had to do a delayed dexopt of an app before launching
1401     * it, to increase the ANR timeouts in that case.
1402     */
1403    boolean mDidDexOpt;
1404
1405    /**
1406     * Set if the systemServer made a call to enterSafeMode.
1407     */
1408    boolean mSafeMode;
1409
1410    /**
1411     * If true, we are running under a test environment so will sample PSS from processes
1412     * much more rapidly to try to collect better data when the tests are rapidly
1413     * running through apps.
1414     */
1415    boolean mTestPssMode = false;
1416
1417    String mDebugApp = null;
1418    boolean mWaitForDebugger = false;
1419    boolean mDebugTransient = false;
1420    String mOrigDebugApp = null;
1421    boolean mOrigWaitForDebugger = false;
1422    boolean mAlwaysFinishActivities = false;
1423    boolean mForceResizableActivities;
1424    boolean mSupportsMultiWindow;
1425    boolean mSupportsSplitScreenMultiWindow;
1426    boolean mSupportsFreeformWindowManagement;
1427    boolean mSupportsPictureInPicture;
1428    boolean mSupportsLeanbackOnly;
1429    IActivityController mController = null;
1430    boolean mControllerIsAMonkey = false;
1431    String mProfileApp = null;
1432    ProcessRecord mProfileProc = null;
1433    String mProfileFile;
1434    ParcelFileDescriptor mProfileFd;
1435    int mSamplingInterval = 0;
1436    boolean mAutoStopProfiler = false;
1437    boolean mStreamingOutput = false;
1438    int mProfileType = 0;
1439    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1440    String mMemWatchDumpProcName;
1441    String mMemWatchDumpFile;
1442    int mMemWatchDumpPid;
1443    int mMemWatchDumpUid;
1444    String mTrackAllocationApp = null;
1445    String mNativeDebuggingApp = null;
1446
1447    final long[] mTmpLong = new long[2];
1448
1449    private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet();
1450
1451    /**
1452     * A global counter for generating sequence numbers.
1453     * This value will be used when incrementing sequence numbers in individual uidRecords.
1454     *
1455     * Having a global counter ensures that seq numbers are monotonically increasing for a
1456     * particular uid even when the uidRecord is re-created.
1457     */
1458    @GuardedBy("this")
1459    @VisibleForTesting
1460    long mProcStateSeqCounter = 0;
1461
1462    static final class ProcessChangeItem {
1463        static final int CHANGE_ACTIVITIES = 1<<0;
1464        int changes;
1465        int uid;
1466        int pid;
1467        int processState;
1468        boolean foregroundActivities;
1469    }
1470
1471    static final class UidObserverRegistration {
1472        final int uid;
1473        final String pkg;
1474        final int which;
1475        final int cutpoint;
1476
1477        final SparseIntArray lastProcStates;
1478
1479        UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) {
1480            uid = _uid;
1481            pkg = _pkg;
1482            which = _which;
1483            cutpoint = _cutpoint;
1484            if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
1485                lastProcStates = new SparseIntArray();
1486            } else {
1487                lastProcStates = null;
1488            }
1489        }
1490    }
1491
1492    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1493    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1494
1495    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1496    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1497
1498    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1499    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1500
1501    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1502    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1503
1504    /**
1505     * Runtime CPU use collection thread.  This object's lock is used to
1506     * perform synchronization with the thread (notifying it to run).
1507     */
1508    final Thread mProcessCpuThread;
1509
1510    /**
1511     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1512     * Must acquire this object's lock when accessing it.
1513     * NOTE: this lock will be held while doing long operations (trawling
1514     * through all processes in /proc), so it should never be acquired by
1515     * any critical paths such as when holding the main activity manager lock.
1516     */
1517    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1518            MONITOR_THREAD_CPU_USAGE);
1519    final AtomicLong mLastCpuTime = new AtomicLong(0);
1520    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1521    final CountDownLatch mProcessCpuInitLatch = new CountDownLatch(1);
1522
1523    long mLastWriteTime = 0;
1524
1525    /**
1526     * Used to retain an update lock when the foreground activity is in
1527     * immersive mode.
1528     */
1529    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1530
1531    /**
1532     * Set to true after the system has finished booting.
1533     */
1534    boolean mBooted = false;
1535
1536    WindowManagerService mWindowManager;
1537    final ActivityThread mSystemThread;
1538
1539    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1540        final ProcessRecord mApp;
1541        final int mPid;
1542        final IApplicationThread mAppThread;
1543
1544        AppDeathRecipient(ProcessRecord app, int pid,
1545                IApplicationThread thread) {
1546            if (DEBUG_ALL) Slog.v(
1547                TAG, "New death recipient " + this
1548                + " for thread " + thread.asBinder());
1549            mApp = app;
1550            mPid = pid;
1551            mAppThread = thread;
1552        }
1553
1554        @Override
1555        public void binderDied() {
1556            if (DEBUG_ALL) Slog.v(
1557                TAG, "Death received in " + this
1558                + " for thread " + mAppThread.asBinder());
1559            synchronized(ActivityManagerService.this) {
1560                appDiedLocked(mApp, mPid, mAppThread, true);
1561            }
1562        }
1563    }
1564
1565    static final int SHOW_ERROR_UI_MSG = 1;
1566    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1567    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1568    static final int UPDATE_CONFIGURATION_MSG = 4;
1569    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1570    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1571    static final int SERVICE_TIMEOUT_MSG = 12;
1572    static final int UPDATE_TIME_ZONE = 13;
1573    static final int SHOW_UID_ERROR_UI_MSG = 14;
1574    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1575    static final int PROC_START_TIMEOUT_MSG = 20;
1576    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1577    static final int KILL_APPLICATION_MSG = 22;
1578    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1579    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1580    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1581    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1582    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1583    static final int CLEAR_DNS_CACHE_MSG = 28;
1584    static final int UPDATE_HTTP_PROXY_MSG = 29;
1585    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1586    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1587    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1588    static final int REPORT_MEM_USAGE_MSG = 33;
1589    static final int REPORT_USER_SWITCH_MSG = 34;
1590    static final int CONTINUE_USER_SWITCH_MSG = 35;
1591    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1592    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1593    static final int PERSIST_URI_GRANTS_MSG = 38;
1594    static final int REQUEST_ALL_PSS_MSG = 39;
1595    static final int START_PROFILES_MSG = 40;
1596    static final int UPDATE_TIME_PREFERENCE_MSG = 41;
1597    static final int SYSTEM_USER_START_MSG = 42;
1598    static final int SYSTEM_USER_CURRENT_MSG = 43;
1599    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1600    static final int FINISH_BOOTING_MSG = 45;
1601    static final int START_USER_SWITCH_UI_MSG = 46;
1602    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1603    static final int DISMISS_DIALOG_UI_MSG = 48;
1604    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
1605    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
1606    static final int DELETE_DUMPHEAP_MSG = 51;
1607    static final int FOREGROUND_PROFILE_CHANGED_MSG = 52;
1608    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
1609    static final int REPORT_TIME_TRACKER_MSG = 54;
1610    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 55;
1611    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
1612    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
1613    static final int IDLE_UIDS_MSG = 58;
1614    static final int SYSTEM_USER_UNLOCK_MSG = 59;
1615    static final int LOG_STACK_STATE = 60;
1616    static final int VR_MODE_CHANGE_MSG = 61;
1617    static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 62;
1618    static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
1619    static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 64;
1620    static final int NOTIFY_VR_SLEEPING_MSG = 65;
1621    static final int START_USER_SWITCH_FG_MSG = 712;
1622
1623    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1624    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1625    static final int FIRST_COMPAT_MODE_MSG = 300;
1626    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1627
1628    static ServiceThread sKillThread = null;
1629    static KillHandler sKillHandler = null;
1630
1631    CompatModeDialog mCompatModeDialog;
1632    UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1633    long mLastMemUsageReportTime = 0;
1634
1635    /**
1636     * Flag whether the current user is a "monkey", i.e. whether
1637     * the UI is driven by a UI automation tool.
1638     */
1639    private boolean mUserIsMonkey;
1640
1641    /** Flag whether the device has a Recents UI */
1642    boolean mHasRecents;
1643
1644    /** The dimensions of the thumbnails in the Recents UI. */
1645    int mThumbnailWidth;
1646    int mThumbnailHeight;
1647    float mFullscreenThumbnailScale;
1648
1649    final ServiceThread mHandlerThread;
1650    final MainHandler mHandler;
1651    final UiHandler mUiHandler;
1652
1653    final ActivityManagerConstants mConstants;
1654
1655    PackageManagerInternal mPackageManagerInt;
1656
1657    // VoiceInteraction session ID that changes for each new request except when
1658    // being called for multiwindow assist in a single session.
1659    private int mViSessionId = 1000;
1660
1661    final boolean mPermissionReviewRequired;
1662
1663    /**
1664     * Current global configuration information. Contains general settings for the entire system,
1665     * also corresponds to the merged configuration of the default display.
1666     */
1667    Configuration getGlobalConfiguration() {
1668        return mStackSupervisor.getConfiguration();
1669    }
1670
1671    final class KillHandler extends Handler {
1672        static final int KILL_PROCESS_GROUP_MSG = 4000;
1673
1674        public KillHandler(Looper looper) {
1675            super(looper, null, true);
1676        }
1677
1678        @Override
1679        public void handleMessage(Message msg) {
1680            switch (msg.what) {
1681                case KILL_PROCESS_GROUP_MSG:
1682                {
1683                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1684                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1685                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1686                }
1687                break;
1688
1689                default:
1690                    super.handleMessage(msg);
1691            }
1692        }
1693    }
1694
1695    final class UiHandler extends Handler {
1696        public UiHandler() {
1697            super(com.android.server.UiThread.get().getLooper(), null, true);
1698        }
1699
1700        @Override
1701        public void handleMessage(Message msg) {
1702            switch (msg.what) {
1703            case SHOW_ERROR_UI_MSG: {
1704                mAppErrors.handleShowAppErrorUi(msg);
1705                ensureBootCompleted();
1706            } break;
1707            case SHOW_NOT_RESPONDING_UI_MSG: {
1708                mAppErrors.handleShowAnrUi(msg);
1709                ensureBootCompleted();
1710            } break;
1711            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1712                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1713                synchronized (ActivityManagerService.this) {
1714                    ProcessRecord proc = (ProcessRecord) data.get("app");
1715                    if (proc == null) {
1716                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1717                        break;
1718                    }
1719                    if (proc.crashDialog != null) {
1720                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1721                        return;
1722                    }
1723                    AppErrorResult res = (AppErrorResult) data.get("result");
1724                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1725                        Dialog d = new StrictModeViolationDialog(mContext,
1726                                ActivityManagerService.this, res, proc);
1727                        d.show();
1728                        proc.crashDialog = d;
1729                    } else {
1730                        // The device is asleep, so just pretend that the user
1731                        // saw a crash dialog and hit "force quit".
1732                        res.set(0);
1733                    }
1734                }
1735                ensureBootCompleted();
1736            } break;
1737            case SHOW_FACTORY_ERROR_UI_MSG: {
1738                Dialog d = new FactoryErrorDialog(
1739                    mContext, msg.getData().getCharSequence("msg"));
1740                d.show();
1741                ensureBootCompleted();
1742            } break;
1743            case WAIT_FOR_DEBUGGER_UI_MSG: {
1744                synchronized (ActivityManagerService.this) {
1745                    ProcessRecord app = (ProcessRecord)msg.obj;
1746                    if (msg.arg1 != 0) {
1747                        if (!app.waitedForDebugger) {
1748                            Dialog d = new AppWaitingForDebuggerDialog(
1749                                    ActivityManagerService.this,
1750                                    mContext, app);
1751                            app.waitDialog = d;
1752                            app.waitedForDebugger = true;
1753                            d.show();
1754                        }
1755                    } else {
1756                        if (app.waitDialog != null) {
1757                            app.waitDialog.dismiss();
1758                            app.waitDialog = null;
1759                        }
1760                    }
1761                }
1762            } break;
1763            case SHOW_UID_ERROR_UI_MSG: {
1764                if (mShowDialogs) {
1765                    AlertDialog d = new BaseErrorDialog(mContext);
1766                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1767                    d.setCancelable(false);
1768                    d.setTitle(mContext.getText(R.string.android_system_label));
1769                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1770                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1771                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1772                    d.show();
1773                }
1774            } break;
1775            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1776                if (mShowDialogs) {
1777                    AlertDialog d = new BaseErrorDialog(mContext);
1778                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1779                    d.setCancelable(false);
1780                    d.setTitle(mContext.getText(R.string.android_system_label));
1781                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1782                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1783                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1784                    d.show();
1785                }
1786            } break;
1787            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1788                synchronized (ActivityManagerService.this) {
1789                    ActivityRecord ar = (ActivityRecord) msg.obj;
1790                    if (mCompatModeDialog != null) {
1791                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1792                                ar.info.applicationInfo.packageName)) {
1793                            return;
1794                        }
1795                        mCompatModeDialog.dismiss();
1796                        mCompatModeDialog = null;
1797                    }
1798                    if (ar != null && false) {
1799                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1800                                ar.packageName)) {
1801                            int mode = mCompatModePackages.computeCompatModeLocked(
1802                                    ar.info.applicationInfo);
1803                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1804                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1805                                mCompatModeDialog = new CompatModeDialog(
1806                                        ActivityManagerService.this, mContext,
1807                                        ar.info.applicationInfo);
1808                                mCompatModeDialog.show();
1809                            }
1810                        }
1811                    }
1812                }
1813                break;
1814            }
1815            case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1816                synchronized (ActivityManagerService.this) {
1817                    final ActivityRecord ar = (ActivityRecord) msg.obj;
1818                    if (mUnsupportedDisplaySizeDialog != null) {
1819                        mUnsupportedDisplaySizeDialog.dismiss();
1820                        mUnsupportedDisplaySizeDialog = null;
1821                    }
1822                    if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1823                            ar.packageName)) {
1824                        // TODO(multi-display): Show dialog on appropriate display.
1825                        mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1826                                ActivityManagerService.this, mContext, ar.info.applicationInfo);
1827                        mUnsupportedDisplaySizeDialog.show();
1828                    }
1829                }
1830                break;
1831            }
1832            case START_USER_SWITCH_UI_MSG: {
1833                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1834                break;
1835            }
1836            case DISMISS_DIALOG_UI_MSG: {
1837                final Dialog d = (Dialog) msg.obj;
1838                d.dismiss();
1839                break;
1840            }
1841            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1842                dispatchProcessesChanged();
1843                break;
1844            }
1845            case DISPATCH_PROCESS_DIED_UI_MSG: {
1846                final int pid = msg.arg1;
1847                final int uid = msg.arg2;
1848                dispatchProcessDied(pid, uid);
1849                break;
1850            }
1851            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1852                dispatchUidsChanged();
1853            } break;
1854            }
1855        }
1856    }
1857
1858    final class MainHandler extends Handler {
1859        public MainHandler(Looper looper) {
1860            super(looper, null, true);
1861        }
1862
1863        @Override
1864        public void handleMessage(Message msg) {
1865            switch (msg.what) {
1866            case UPDATE_CONFIGURATION_MSG: {
1867                final ContentResolver resolver = mContext.getContentResolver();
1868                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1869                        msg.arg1);
1870            } break;
1871            case GC_BACKGROUND_PROCESSES_MSG: {
1872                synchronized (ActivityManagerService.this) {
1873                    performAppGcsIfAppropriateLocked();
1874                }
1875            } break;
1876            case SERVICE_TIMEOUT_MSG: {
1877                if (mDidDexOpt) {
1878                    mDidDexOpt = false;
1879                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1880                    nmsg.obj = msg.obj;
1881                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1882                    return;
1883                }
1884                mServices.serviceTimeout((ProcessRecord)msg.obj);
1885            } break;
1886            case UPDATE_TIME_ZONE: {
1887                synchronized (ActivityManagerService.this) {
1888                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1889                        ProcessRecord r = mLruProcesses.get(i);
1890                        if (r.thread != null) {
1891                            try {
1892                                r.thread.updateTimeZone();
1893                            } catch (RemoteException ex) {
1894                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1895                            }
1896                        }
1897                    }
1898                }
1899            } break;
1900            case CLEAR_DNS_CACHE_MSG: {
1901                synchronized (ActivityManagerService.this) {
1902                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1903                        ProcessRecord r = mLruProcesses.get(i);
1904                        if (r.thread != null) {
1905                            try {
1906                                r.thread.clearDnsCache();
1907                            } catch (RemoteException ex) {
1908                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1909                            }
1910                        }
1911                    }
1912                }
1913            } break;
1914            case UPDATE_HTTP_PROXY_MSG: {
1915                ProxyInfo proxy = (ProxyInfo)msg.obj;
1916                String host = "";
1917                String port = "";
1918                String exclList = "";
1919                Uri pacFileUrl = Uri.EMPTY;
1920                if (proxy != null) {
1921                    host = proxy.getHost();
1922                    port = Integer.toString(proxy.getPort());
1923                    exclList = proxy.getExclusionListAsString();
1924                    pacFileUrl = proxy.getPacFileUrl();
1925                }
1926                synchronized (ActivityManagerService.this) {
1927                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1928                        ProcessRecord r = mLruProcesses.get(i);
1929                        if (r.thread != null) {
1930                            try {
1931                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1932                            } catch (RemoteException ex) {
1933                                Slog.w(TAG, "Failed to update http proxy for: " +
1934                                        r.info.processName);
1935                            }
1936                        }
1937                    }
1938                }
1939            } break;
1940            case PROC_START_TIMEOUT_MSG: {
1941                if (mDidDexOpt) {
1942                    mDidDexOpt = false;
1943                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1944                    nmsg.obj = msg.obj;
1945                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1946                    return;
1947                }
1948                ProcessRecord app = (ProcessRecord)msg.obj;
1949                synchronized (ActivityManagerService.this) {
1950                    processStartTimedOutLocked(app);
1951                }
1952            } break;
1953            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1954                ProcessRecord app = (ProcessRecord)msg.obj;
1955                synchronized (ActivityManagerService.this) {
1956                    processContentProviderPublishTimedOutLocked(app);
1957                }
1958            } break;
1959            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1960                synchronized (ActivityManagerService.this) {
1961                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1962                }
1963            } break;
1964            case KILL_APPLICATION_MSG: {
1965                synchronized (ActivityManagerService.this) {
1966                    final int appId = msg.arg1;
1967                    final int userId = msg.arg2;
1968                    Bundle bundle = (Bundle)msg.obj;
1969                    String pkg = bundle.getString("pkg");
1970                    String reason = bundle.getString("reason");
1971                    forceStopPackageLocked(pkg, appId, false, false, true, false,
1972                            false, userId, reason);
1973                }
1974            } break;
1975            case FINALIZE_PENDING_INTENT_MSG: {
1976                ((PendingIntentRecord)msg.obj).completeFinalize();
1977            } break;
1978            case POST_HEAVY_NOTIFICATION_MSG: {
1979                INotificationManager inm = NotificationManager.getService();
1980                if (inm == null) {
1981                    return;
1982                }
1983
1984                ActivityRecord root = (ActivityRecord)msg.obj;
1985                ProcessRecord process = root.app;
1986                if (process == null) {
1987                    return;
1988                }
1989
1990                try {
1991                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1992                    String text = mContext.getString(R.string.heavy_weight_notification,
1993                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1994                    Notification notification =
1995                            new Notification.Builder(context, SystemNotificationChannels.DEVELOPER)
1996                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1997                            .setWhen(0)
1998                            .setOngoing(true)
1999                            .setTicker(text)
2000                            .setColor(mContext.getColor(
2001                                    com.android.internal.R.color.system_notification_accent_color))
2002                            .setContentTitle(text)
2003                            .setContentText(
2004                                    mContext.getText(R.string.heavy_weight_notification_detail))
2005                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2006                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2007                                    new UserHandle(root.userId)))
2008                            .build();
2009                    try {
2010                        int[] outId = new int[1];
2011                        inm.enqueueNotificationWithTag("android", "android", null,
2012                                R.string.heavy_weight_notification,
2013                                notification, outId, root.userId);
2014                    } catch (RuntimeException e) {
2015                        Slog.w(ActivityManagerService.TAG,
2016                                "Error showing notification for heavy-weight app", e);
2017                    } catch (RemoteException e) {
2018                    }
2019                } catch (NameNotFoundException e) {
2020                    Slog.w(TAG, "Unable to create context for heavy notification", e);
2021                }
2022            } break;
2023            case CANCEL_HEAVY_NOTIFICATION_MSG: {
2024                INotificationManager inm = NotificationManager.getService();
2025                if (inm == null) {
2026                    return;
2027                }
2028                try {
2029                    inm.cancelNotificationWithTag("android", null,
2030                            R.string.heavy_weight_notification,  msg.arg1);
2031                } catch (RuntimeException e) {
2032                    Slog.w(ActivityManagerService.TAG,
2033                            "Error canceling notification for service", e);
2034                } catch (RemoteException e) {
2035                }
2036            } break;
2037            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
2038                synchronized (ActivityManagerService.this) {
2039                    checkExcessivePowerUsageLocked(true);
2040                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
2041                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
2042                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
2043                }
2044            } break;
2045            case REPORT_MEM_USAGE_MSG: {
2046                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
2047                Thread thread = new Thread() {
2048                    @Override public void run() {
2049                        reportMemUsage(memInfos);
2050                    }
2051                };
2052                thread.start();
2053                break;
2054            }
2055            case START_USER_SWITCH_FG_MSG: {
2056                mUserController.startUserInForeground(msg.arg1);
2057                break;
2058            }
2059            case REPORT_USER_SWITCH_MSG: {
2060                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2061                break;
2062            }
2063            case CONTINUE_USER_SWITCH_MSG: {
2064                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2065                break;
2066            }
2067            case USER_SWITCH_TIMEOUT_MSG: {
2068                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2069                break;
2070            }
2071            case IMMERSIVE_MODE_LOCK_MSG: {
2072                final boolean nextState = (msg.arg1 != 0);
2073                if (mUpdateLock.isHeld() != nextState) {
2074                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
2075                            "Applying new update lock state '" + nextState
2076                            + "' for " + (ActivityRecord)msg.obj);
2077                    if (nextState) {
2078                        mUpdateLock.acquire();
2079                    } else {
2080                        mUpdateLock.release();
2081                    }
2082                }
2083                break;
2084            }
2085            case PERSIST_URI_GRANTS_MSG: {
2086                writeGrantedUriPermissions();
2087                break;
2088            }
2089            case REQUEST_ALL_PSS_MSG: {
2090                synchronized (ActivityManagerService.this) {
2091                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
2092                }
2093                break;
2094            }
2095            case START_PROFILES_MSG: {
2096                synchronized (ActivityManagerService.this) {
2097                    mUserController.startProfilesLocked();
2098                }
2099                break;
2100            }
2101            case UPDATE_TIME_PREFERENCE_MSG: {
2102                // The user's time format preference might have changed.
2103                // For convenience we re-use the Intent extra values.
2104                synchronized (ActivityManagerService.this) {
2105                    for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2106                        ProcessRecord r = mLruProcesses.get(i);
2107                        if (r.thread != null) {
2108                            try {
2109                                r.thread.updateTimePrefs(msg.arg1);
2110                            } catch (RemoteException ex) {
2111                                Slog.w(TAG, "Failed to update preferences for: "
2112                                        + r.info.processName);
2113                            }
2114                        }
2115                    }
2116                }
2117                break;
2118            }
2119            case SYSTEM_USER_START_MSG: {
2120                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2121                        Integer.toString(msg.arg1), msg.arg1);
2122                mSystemServiceManager.startUser(msg.arg1);
2123                break;
2124            }
2125            case SYSTEM_USER_UNLOCK_MSG: {
2126                final int userId = msg.arg1;
2127                mSystemServiceManager.unlockUser(userId);
2128                synchronized (ActivityManagerService.this) {
2129                    mRecentTasks.loadUserRecentsLocked(userId);
2130                }
2131                if (userId == UserHandle.USER_SYSTEM) {
2132                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2133                }
2134                installEncryptionUnawareProviders(userId);
2135                mUserController.finishUserUnlocked((UserState) msg.obj);
2136                break;
2137            }
2138            case SYSTEM_USER_CURRENT_MSG: {
2139                mBatteryStatsService.noteEvent(
2140                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2141                        Integer.toString(msg.arg2), msg.arg2);
2142                mBatteryStatsService.noteEvent(
2143                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2144                        Integer.toString(msg.arg1), msg.arg1);
2145                mSystemServiceManager.switchUser(msg.arg1);
2146                break;
2147            }
2148            case ENTER_ANIMATION_COMPLETE_MSG: {
2149                synchronized (ActivityManagerService.this) {
2150                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2151                    if (r != null && r.app != null && r.app.thread != null) {
2152                        try {
2153                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2154                        } catch (RemoteException e) {
2155                        }
2156                    }
2157                }
2158                break;
2159            }
2160            case FINISH_BOOTING_MSG: {
2161                if (msg.arg1 != 0) {
2162                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2163                    finishBooting();
2164                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2165                }
2166                if (msg.arg2 != 0) {
2167                    enableScreenAfterBoot();
2168                }
2169                break;
2170            }
2171            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2172                try {
2173                    Locale l = (Locale) msg.obj;
2174                    IBinder service = ServiceManager.getService("mount");
2175                    IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
2176                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2177                    storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2178                } catch (RemoteException e) {
2179                    Log.e(TAG, "Error storing locale for decryption UI", e);
2180                }
2181                break;
2182            }
2183            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2184                final int uid = msg.arg1;
2185                final byte[] firstPacket = (byte[]) msg.obj;
2186
2187                synchronized (mPidsSelfLocked) {
2188                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2189                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2190                        if (p.uid == uid) {
2191                            try {
2192                                p.thread.notifyCleartextNetwork(firstPacket);
2193                            } catch (RemoteException ignored) {
2194                            }
2195                        }
2196                    }
2197                }
2198                break;
2199            }
2200            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2201                final String procName;
2202                final int uid;
2203                final long memLimit;
2204                final String reportPackage;
2205                synchronized (ActivityManagerService.this) {
2206                    procName = mMemWatchDumpProcName;
2207                    uid = mMemWatchDumpUid;
2208                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2209                    if (val == null) {
2210                        val = mMemWatchProcesses.get(procName, 0);
2211                    }
2212                    if (val != null) {
2213                        memLimit = val.first;
2214                        reportPackage = val.second;
2215                    } else {
2216                        memLimit = 0;
2217                        reportPackage = null;
2218                    }
2219                }
2220                if (procName == null) {
2221                    return;
2222                }
2223
2224                if (DEBUG_PSS) Slog.d(TAG_PSS,
2225                        "Showing dump heap notification from " + procName + "/" + uid);
2226
2227                INotificationManager inm = NotificationManager.getService();
2228                if (inm == null) {
2229                    return;
2230                }
2231
2232                String text = mContext.getString(R.string.dump_heap_notification, procName);
2233
2234
2235                Intent deleteIntent = new Intent();
2236                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2237                Intent intent = new Intent();
2238                intent.setClassName("android", DumpHeapActivity.class.getName());
2239                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2240                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2241                if (reportPackage != null) {
2242                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2243                }
2244                int userId = UserHandle.getUserId(uid);
2245                Notification notification =
2246                        new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER)
2247                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2248                        .setWhen(0)
2249                        .setOngoing(true)
2250                        .setAutoCancel(true)
2251                        .setTicker(text)
2252                        .setColor(mContext.getColor(
2253                                com.android.internal.R.color.system_notification_accent_color))
2254                        .setContentTitle(text)
2255                        .setContentText(
2256                                mContext.getText(R.string.dump_heap_notification_detail))
2257                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2258                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2259                                new UserHandle(userId)))
2260                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2261                                deleteIntent, 0, UserHandle.SYSTEM))
2262                        .build();
2263
2264                try {
2265                    int[] outId = new int[1];
2266                    inm.enqueueNotificationWithTag("android", "android", null,
2267                            R.string.dump_heap_notification,
2268                            notification, outId, userId);
2269                } catch (RuntimeException e) {
2270                    Slog.w(ActivityManagerService.TAG,
2271                            "Error showing notification for dump heap", e);
2272                } catch (RemoteException e) {
2273                }
2274            } break;
2275            case DELETE_DUMPHEAP_MSG: {
2276                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2277                        DumpHeapActivity.JAVA_URI,
2278                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2279                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2280                        UserHandle.myUserId());
2281                synchronized (ActivityManagerService.this) {
2282                    mMemWatchDumpFile = null;
2283                    mMemWatchDumpProcName = null;
2284                    mMemWatchDumpPid = -1;
2285                    mMemWatchDumpUid = -1;
2286                }
2287            } break;
2288            case FOREGROUND_PROFILE_CHANGED_MSG: {
2289                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2290            } break;
2291            case REPORT_TIME_TRACKER_MSG: {
2292                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2293                tracker.deliverResult(mContext);
2294            } break;
2295            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2296                mUserController.dispatchUserSwitchComplete(msg.arg1);
2297            } break;
2298            case REPORT_LOCKED_BOOT_COMPLETE_MSG: {
2299                mUserController.dispatchLockedBootComplete(msg.arg1);
2300            } break;
2301            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2302                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2303                try {
2304                    connection.shutdown();
2305                } catch (RemoteException e) {
2306                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2307                }
2308                // Only a UiAutomation can set this flag and now that
2309                // it is finished we make sure it is reset to its default.
2310                mUserIsMonkey = false;
2311            } break;
2312            case IDLE_UIDS_MSG: {
2313                idleUids();
2314            } break;
2315            case VR_MODE_CHANGE_MSG: {
2316                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2317                if (vrService == null) {
2318                    break;
2319                }
2320                final ActivityRecord r = (ActivityRecord) msg.obj;
2321                boolean vrMode;
2322                ComponentName requestedPackage;
2323                ComponentName callingPackage;
2324                int userId;
2325                synchronized (ActivityManagerService.this) {
2326                    vrMode = r.requestedVrComponent != null;
2327                    requestedPackage = r.requestedVrComponent;
2328                    userId = r.userId;
2329                    callingPackage = r.info.getComponentName();
2330                    if (mInVrMode != vrMode) {
2331                        mInVrMode = vrMode;
2332                        mShowDialogs = shouldShowDialogs(getGlobalConfiguration(), mInVrMode);
2333                        if (r.app != null) {
2334                            ProcessRecord proc = r.app;
2335                            if (proc.vrThreadTid > 0) {
2336                                if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
2337                                    try {
2338                                        if (mInVrMode == true) {
2339                                            Process.setThreadScheduler(proc.vrThreadTid,
2340                                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
2341                                        } else {
2342                                            Process.setThreadScheduler(proc.vrThreadTid,
2343                                                Process.SCHED_OTHER, 0);
2344                                        }
2345                                    } catch (IllegalArgumentException e) {
2346                                        Slog.w(TAG, "Failed to set scheduling policy, thread does"
2347                                                + " not exist:\n" + e);
2348                                    }
2349                                }
2350                            }
2351                        }
2352                    }
2353                }
2354                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2355            } break;
2356            case NOTIFY_VR_SLEEPING_MSG: {
2357                notifyVrManagerOfSleepState(msg.arg1 != 0);
2358            } break;
2359            case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
2360                synchronized (ActivityManagerService.this) {
2361                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2362                        ProcessRecord r = mLruProcesses.get(i);
2363                        if (r.thread != null) {
2364                            try {
2365                                r.thread.handleTrustStorageUpdate();
2366                            } catch (RemoteException ex) {
2367                                Slog.w(TAG, "Failed to handle trust storage update for: " +
2368                                        r.info.processName);
2369                            }
2370                        }
2371                    }
2372                }
2373            } break;
2374            }
2375        }
2376    };
2377
2378    static final int COLLECT_PSS_BG_MSG = 1;
2379
2380    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2381        @Override
2382        public void handleMessage(Message msg) {
2383            switch (msg.what) {
2384            case COLLECT_PSS_BG_MSG: {
2385                long start = SystemClock.uptimeMillis();
2386                MemInfoReader memInfo = null;
2387                synchronized (ActivityManagerService.this) {
2388                    if (mFullPssPending) {
2389                        mFullPssPending = false;
2390                        memInfo = new MemInfoReader();
2391                    }
2392                }
2393                if (memInfo != null) {
2394                    updateCpuStatsNow();
2395                    long nativeTotalPss = 0;
2396                    final List<ProcessCpuTracker.Stats> stats;
2397                    synchronized (mProcessCpuTracker) {
2398                        stats = mProcessCpuTracker.getStats( (st)-> {
2399                            return st.vsize > 0 && st.uid < Process.FIRST_APPLICATION_UID;
2400                        });
2401                    }
2402                    final int N = stats.size();
2403                    for (int j = 0; j < N; j++) {
2404                        synchronized (mPidsSelfLocked) {
2405                            if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2406                                // This is one of our own processes; skip it.
2407                                continue;
2408                            }
2409                        }
2410                        nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2411                    }
2412                    memInfo.readMemInfo();
2413                    synchronized (ActivityManagerService.this) {
2414                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2415                                + (SystemClock.uptimeMillis()-start) + "ms");
2416                        final long cachedKb = memInfo.getCachedSizeKb();
2417                        final long freeKb = memInfo.getFreeSizeKb();
2418                        final long zramKb = memInfo.getZramTotalSizeKb();
2419                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2420                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2421                                kernelKb*1024, nativeTotalPss*1024);
2422                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2423                                nativeTotalPss);
2424                    }
2425                }
2426
2427                int num = 0;
2428                long[] tmp = new long[2];
2429                do {
2430                    ProcessRecord proc;
2431                    int procState;
2432                    int pid;
2433                    long lastPssTime;
2434                    synchronized (ActivityManagerService.this) {
2435                        if (mPendingPssProcesses.size() <= 0) {
2436                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2437                                    "Collected PSS of " + num + " processes in "
2438                                    + (SystemClock.uptimeMillis() - start) + "ms");
2439                            mPendingPssProcesses.clear();
2440                            return;
2441                        }
2442                        proc = mPendingPssProcesses.remove(0);
2443                        procState = proc.pssProcState;
2444                        lastPssTime = proc.lastPssTime;
2445                        if (proc.thread != null && procState == proc.setProcState
2446                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2447                                        < SystemClock.uptimeMillis()) {
2448                            pid = proc.pid;
2449                        } else {
2450                            proc = null;
2451                            pid = 0;
2452                        }
2453                    }
2454                    if (proc != null) {
2455                        long pss = Debug.getPss(pid, tmp, null);
2456                        synchronized (ActivityManagerService.this) {
2457                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2458                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2459                                num++;
2460                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2461                                        SystemClock.uptimeMillis());
2462                            }
2463                        }
2464                    }
2465                } while (true);
2466            }
2467            }
2468        }
2469    };
2470
2471    public void setSystemProcess() {
2472        try {
2473            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2474            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2475            ServiceManager.addService("meminfo", new MemBinder(this));
2476            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2477            ServiceManager.addService("dbinfo", new DbBinder(this));
2478            if (MONITOR_CPU_USAGE) {
2479                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2480            }
2481            ServiceManager.addService("permission", new PermissionController(this));
2482            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2483
2484            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2485                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2486            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2487
2488            synchronized (this) {
2489                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2490                app.persistent = true;
2491                app.pid = MY_PID;
2492                app.maxAdj = ProcessList.SYSTEM_ADJ;
2493                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2494                synchronized (mPidsSelfLocked) {
2495                    mPidsSelfLocked.put(app.pid, app);
2496                }
2497                updateLruProcessLocked(app, false, null);
2498                updateOomAdjLocked();
2499            }
2500        } catch (PackageManager.NameNotFoundException e) {
2501            throw new RuntimeException(
2502                    "Unable to find android system package", e);
2503        }
2504    }
2505
2506    public void setWindowManager(WindowManagerService wm) {
2507        mWindowManager = wm;
2508        mStackSupervisor.setWindowManager(wm);
2509        mActivityStarter.setWindowManager(wm);
2510    }
2511
2512    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2513        mUsageStatsService = usageStatsManager;
2514    }
2515
2516    public void startObservingNativeCrashes() {
2517        final NativeCrashListener ncl = new NativeCrashListener(this);
2518        ncl.start();
2519    }
2520
2521    public IAppOpsService getAppOpsService() {
2522        return mAppOpsService;
2523    }
2524
2525    static class MemBinder extends Binder {
2526        ActivityManagerService mActivityManagerService;
2527        MemBinder(ActivityManagerService activityManagerService) {
2528            mActivityManagerService = activityManagerService;
2529        }
2530
2531        @Override
2532        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2533            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2534                    != PackageManager.PERMISSION_GRANTED) {
2535                pw.println("Permission Denial: can't dump meminfo from from pid="
2536                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2537                        + " without permission " + android.Manifest.permission.DUMP);
2538                return;
2539            }
2540
2541            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2542        }
2543    }
2544
2545    static class GraphicsBinder extends Binder {
2546        ActivityManagerService mActivityManagerService;
2547        GraphicsBinder(ActivityManagerService activityManagerService) {
2548            mActivityManagerService = activityManagerService;
2549        }
2550
2551        @Override
2552        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2553            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2554                    != PackageManager.PERMISSION_GRANTED) {
2555                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2556                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2557                        + " without permission " + android.Manifest.permission.DUMP);
2558                return;
2559            }
2560
2561            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2562        }
2563    }
2564
2565    static class DbBinder extends Binder {
2566        ActivityManagerService mActivityManagerService;
2567        DbBinder(ActivityManagerService activityManagerService) {
2568            mActivityManagerService = activityManagerService;
2569        }
2570
2571        @Override
2572        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2573            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2574                    != PackageManager.PERMISSION_GRANTED) {
2575                pw.println("Permission Denial: can't dump dbinfo from from pid="
2576                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2577                        + " without permission " + android.Manifest.permission.DUMP);
2578                return;
2579            }
2580
2581            mActivityManagerService.dumpDbInfo(fd, pw, args);
2582        }
2583    }
2584
2585    static class CpuBinder extends Binder {
2586        ActivityManagerService mActivityManagerService;
2587        CpuBinder(ActivityManagerService activityManagerService) {
2588            mActivityManagerService = activityManagerService;
2589        }
2590
2591        @Override
2592        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2593            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2594                    != PackageManager.PERMISSION_GRANTED) {
2595                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2596                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2597                        + " without permission " + android.Manifest.permission.DUMP);
2598                return;
2599            }
2600
2601            synchronized (mActivityManagerService.mProcessCpuTracker) {
2602                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2603                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2604                        SystemClock.uptimeMillis()));
2605            }
2606        }
2607    }
2608
2609    public static final class Lifecycle extends SystemService {
2610        private final ActivityManagerService mService;
2611
2612        public Lifecycle(Context context) {
2613            super(context);
2614            mService = new ActivityManagerService(context);
2615        }
2616
2617        @Override
2618        public void onStart() {
2619            mService.start();
2620        }
2621
2622        public ActivityManagerService getService() {
2623            return mService;
2624        }
2625    }
2626
2627    @VisibleForTesting
2628    public ActivityManagerService() {
2629        GL_ES_VERSION = 0;
2630        mActivityStarter = null;
2631        mAppErrors = null;
2632        mAppOpsService = null;
2633        mBatteryStatsService = null;
2634        mCompatModePackages = null;
2635        mConstants = null;
2636        mGrantFile = null;
2637        mHandler = null;
2638        mHandlerThread = null;
2639        mIntentFirewall = null;
2640        mKeyguardController = null;
2641        mPermissionReviewRequired = false;
2642        mProcessCpuThread = null;
2643        mProcessStats = null;
2644        mProviderMap = null;
2645        mRecentTasks = null;
2646        mServices = null;
2647        mStackSupervisor = null;
2648        mSystemThread = null;
2649        mTaskChangeNotificationController = null;
2650        mUiHandler = null;
2651        mUserController = null;
2652    }
2653
2654    // Note: This method is invoked on the main thread but may need to attach various
2655    // handlers to other threads.  So take care to be explicit about the looper.
2656    public ActivityManagerService(Context systemContext) {
2657        mContext = systemContext;
2658        mFactoryTest = FactoryTest.getMode();
2659        mSystemThread = ActivityThread.currentActivityThread();
2660
2661        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2662
2663        mPermissionReviewRequired = mContext.getResources().getBoolean(
2664                com.android.internal.R.bool.config_permissionReviewRequired);
2665
2666        mHandlerThread = new ServiceThread(TAG,
2667                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2668        mHandlerThread.start();
2669        mHandler = new MainHandler(mHandlerThread.getLooper());
2670        mUiHandler = new UiHandler();
2671
2672        mConstants = new ActivityManagerConstants(this, mHandler);
2673
2674        if (DEBUG_BACKGROUND_CHECK) {
2675            Slog.d(TAG, "Enforcing O+ bg restrictions: " + mConstants.ENFORCE_BG_CHECK);
2676            StringBuilder sb = new StringBuilder(200);
2677            sb.append("  ");
2678            for (String a : getBackgroundLaunchBroadcasts()) {
2679                sb.append(' '); sb.append(a);
2680            }
2681            Slog.d(TAG, "Background implicit broadcasts:");
2682            Slog.d(TAG, sb.toString());
2683        }
2684
2685        /* static; one-time init here */
2686        if (sKillHandler == null) {
2687            sKillThread = new ServiceThread(TAG + ":kill",
2688                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2689            sKillThread.start();
2690            sKillHandler = new KillHandler(sKillThread.getLooper());
2691        }
2692
2693        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2694                "foreground", BROADCAST_FG_TIMEOUT, false);
2695        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2696                "background", BROADCAST_BG_TIMEOUT, true);
2697        mBroadcastQueues[0] = mFgBroadcastQueue;
2698        mBroadcastQueues[1] = mBgBroadcastQueue;
2699
2700        mServices = new ActiveServices(this);
2701        mProviderMap = new ProviderMap(this);
2702        mAppErrors = new AppErrors(mContext, this);
2703
2704        // TODO: Move creation of battery stats service outside of activity manager service.
2705        File dataDir = Environment.getDataDirectory();
2706        File systemDir = new File(dataDir, "system");
2707        systemDir.mkdirs();
2708        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2709        mBatteryStatsService.getActiveStatistics().readLocked();
2710        mBatteryStatsService.scheduleWriteToDisk();
2711        mOnBattery = DEBUG_POWER ? true
2712                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2713        mBatteryStatsService.getActiveStatistics().setCallback(this);
2714
2715        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2716
2717        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2718        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2719                new IAppOpsCallback.Stub() {
2720                    @Override public void opChanged(int op, int uid, String packageName) {
2721                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2722                            if (mAppOpsService.checkOperation(op, uid, packageName)
2723                                    != AppOpsManager.MODE_ALLOWED) {
2724                                runInBackgroundDisabled(uid);
2725                            }
2726                        }
2727                    }
2728                });
2729
2730        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2731
2732        mUserController = new UserController(this);
2733
2734        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2735            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2736
2737        if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2738            mUseFifoUiScheduling = true;
2739        }
2740
2741        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2742        mTempConfig.setToDefaults();
2743        mTempConfig.setLocales(LocaleList.getDefault());
2744        mConfigurationSeq = mTempConfig.seq = 1;
2745        mStackSupervisor = new ActivityStackSupervisor(this);
2746        mStackSupervisor.onConfigurationChanged(mTempConfig);
2747        mKeyguardController = mStackSupervisor.mKeyguardController;
2748        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2749        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2750        mTaskChangeNotificationController =
2751                new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
2752        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2753        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2754
2755        mProcessCpuThread = new Thread("CpuTracker") {
2756            @Override
2757            public void run() {
2758                synchronized (mProcessCpuTracker) {
2759                    mProcessCpuInitLatch.countDown();
2760                    mProcessCpuTracker.init();
2761                }
2762                while (true) {
2763                    try {
2764                        try {
2765                            synchronized(this) {
2766                                final long now = SystemClock.uptimeMillis();
2767                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2768                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2769                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2770                                //        + ", write delay=" + nextWriteDelay);
2771                                if (nextWriteDelay < nextCpuDelay) {
2772                                    nextCpuDelay = nextWriteDelay;
2773                                }
2774                                if (nextCpuDelay > 0) {
2775                                    mProcessCpuMutexFree.set(true);
2776                                    this.wait(nextCpuDelay);
2777                                }
2778                            }
2779                        } catch (InterruptedException e) {
2780                        }
2781                        updateCpuStatsNow();
2782                    } catch (Exception e) {
2783                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2784                    }
2785                }
2786            }
2787        };
2788
2789        Watchdog.getInstance().addMonitor(this);
2790        Watchdog.getInstance().addThread(mHandler);
2791    }
2792
2793    public void setSystemServiceManager(SystemServiceManager mgr) {
2794        mSystemServiceManager = mgr;
2795    }
2796
2797    public void setInstaller(Installer installer) {
2798        mInstaller = installer;
2799    }
2800
2801    private void start() {
2802        Process.removeAllProcessGroups();
2803        mProcessCpuThread.start();
2804
2805        mBatteryStatsService.publish(mContext);
2806        mAppOpsService.publish(mContext);
2807        Slog.d("AppOps", "AppOpsService published");
2808        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2809        // Wait for the synchronized block started in mProcessCpuThread,
2810        // so that any other acccess to mProcessCpuTracker from main thread
2811        // will be blocked during mProcessCpuTracker initialization.
2812        try {
2813            mProcessCpuInitLatch.await();
2814        } catch (InterruptedException e) {
2815            Slog.wtf(TAG, "Interrupted wait during start", e);
2816            Thread.currentThread().interrupt();
2817            throw new IllegalStateException("Interrupted wait during start");
2818        }
2819    }
2820
2821    void onUserStoppedLocked(int userId) {
2822        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2823    }
2824
2825    public void initPowerManagement() {
2826        mStackSupervisor.initPowerManagement();
2827        mBatteryStatsService.initPowerManagement();
2828        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2829        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2830        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2831        mVoiceWakeLock.setReferenceCounted(false);
2832    }
2833
2834    private ArraySet<String> getBackgroundLaunchBroadcasts() {
2835        if (mBackgroundLaunchBroadcasts == null) {
2836            mBackgroundLaunchBroadcasts = SystemConfig.getInstance().getAllowImplicitBroadcasts();
2837        }
2838        return mBackgroundLaunchBroadcasts;
2839    }
2840
2841    @Override
2842    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2843            throws RemoteException {
2844        if (code == SYSPROPS_TRANSACTION) {
2845            // We need to tell all apps about the system property change.
2846            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2847            synchronized(this) {
2848                final int NP = mProcessNames.getMap().size();
2849                for (int ip=0; ip<NP; ip++) {
2850                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2851                    final int NA = apps.size();
2852                    for (int ia=0; ia<NA; ia++) {
2853                        ProcessRecord app = apps.valueAt(ia);
2854                        if (app.thread != null) {
2855                            procs.add(app.thread.asBinder());
2856                        }
2857                    }
2858                }
2859            }
2860
2861            int N = procs.size();
2862            for (int i=0; i<N; i++) {
2863                Parcel data2 = Parcel.obtain();
2864                try {
2865                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null,
2866                            Binder.FLAG_ONEWAY);
2867                } catch (RemoteException e) {
2868                }
2869                data2.recycle();
2870            }
2871        }
2872        try {
2873            return super.onTransact(code, data, reply, flags);
2874        } catch (RuntimeException e) {
2875            // The activity manager only throws security exceptions, so let's
2876            // log all others.
2877            if (!(e instanceof SecurityException)) {
2878                Slog.wtf(TAG, "Activity Manager Crash", e);
2879            }
2880            throw e;
2881        }
2882    }
2883
2884    void updateCpuStats() {
2885        final long now = SystemClock.uptimeMillis();
2886        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2887            return;
2888        }
2889        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2890            synchronized (mProcessCpuThread) {
2891                mProcessCpuThread.notify();
2892            }
2893        }
2894    }
2895
2896    void updateCpuStatsNow() {
2897        synchronized (mProcessCpuTracker) {
2898            mProcessCpuMutexFree.set(false);
2899            final long now = SystemClock.uptimeMillis();
2900            boolean haveNewCpuStats = false;
2901
2902            if (MONITOR_CPU_USAGE &&
2903                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2904                mLastCpuTime.set(now);
2905                mProcessCpuTracker.update();
2906                if (mProcessCpuTracker.hasGoodLastStats()) {
2907                    haveNewCpuStats = true;
2908                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2909                    //Slog.i(TAG, "Total CPU usage: "
2910                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2911
2912                    // Slog the cpu usage if the property is set.
2913                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2914                        int user = mProcessCpuTracker.getLastUserTime();
2915                        int system = mProcessCpuTracker.getLastSystemTime();
2916                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2917                        int irq = mProcessCpuTracker.getLastIrqTime();
2918                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2919                        int idle = mProcessCpuTracker.getLastIdleTime();
2920
2921                        int total = user + system + iowait + irq + softIrq + idle;
2922                        if (total == 0) total = 1;
2923
2924                        EventLog.writeEvent(EventLogTags.CPU,
2925                                ((user+system+iowait+irq+softIrq) * 100) / total,
2926                                (user * 100) / total,
2927                                (system * 100) / total,
2928                                (iowait * 100) / total,
2929                                (irq * 100) / total,
2930                                (softIrq * 100) / total);
2931                    }
2932                }
2933            }
2934
2935            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2936            synchronized(bstats) {
2937                synchronized(mPidsSelfLocked) {
2938                    if (haveNewCpuStats) {
2939                        if (bstats.startAddingCpuLocked()) {
2940                            int totalUTime = 0;
2941                            int totalSTime = 0;
2942                            final int N = mProcessCpuTracker.countStats();
2943                            for (int i=0; i<N; i++) {
2944                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2945                                if (!st.working) {
2946                                    continue;
2947                                }
2948                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2949                                totalUTime += st.rel_utime;
2950                                totalSTime += st.rel_stime;
2951                                if (pr != null) {
2952                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2953                                    if (ps == null || !ps.isActive()) {
2954                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2955                                                pr.info.uid, pr.processName);
2956                                    }
2957                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2958                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2959                                } else {
2960                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2961                                    if (ps == null || !ps.isActive()) {
2962                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2963                                                bstats.mapUid(st.uid), st.name);
2964                                    }
2965                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2966                                }
2967                            }
2968                            final int userTime = mProcessCpuTracker.getLastUserTime();
2969                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2970                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2971                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2972                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2973                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2974                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2975                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2976                        }
2977                    }
2978                }
2979
2980                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2981                    mLastWriteTime = now;
2982                    mBatteryStatsService.scheduleWriteToDisk();
2983                }
2984            }
2985        }
2986    }
2987
2988    @Override
2989    public void batteryNeedsCpuUpdate() {
2990        updateCpuStatsNow();
2991    }
2992
2993    @Override
2994    public void batteryPowerChanged(boolean onBattery) {
2995        // When plugging in, update the CPU stats first before changing
2996        // the plug state.
2997        updateCpuStatsNow();
2998        synchronized (this) {
2999            synchronized(mPidsSelfLocked) {
3000                mOnBattery = DEBUG_POWER ? true : onBattery;
3001            }
3002        }
3003    }
3004
3005    @Override
3006    public void batterySendBroadcast(Intent intent) {
3007        synchronized (this) {
3008            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
3009                    AppOpsManager.OP_NONE, null, false, false,
3010                    -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
3011        }
3012    }
3013
3014    /**
3015     * Initialize the application bind args. These are passed to each
3016     * process when the bindApplication() IPC is sent to the process. They're
3017     * lazily setup to make sure the services are running when they're asked for.
3018     */
3019    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
3020        // Isolated processes won't get this optimization, so that we don't
3021        // violate the rules about which services they have access to.
3022        if (isolated) {
3023            if (mIsolatedAppBindArgs == null) {
3024                mIsolatedAppBindArgs = new HashMap<>();
3025                mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
3026            }
3027            return mIsolatedAppBindArgs;
3028        }
3029
3030        if (mAppBindArgs == null) {
3031            mAppBindArgs = new HashMap<>();
3032
3033            // Setup the application init args
3034            mAppBindArgs.put("package", ServiceManager.getService("package"));
3035            mAppBindArgs.put("window", ServiceManager.getService("window"));
3036            mAppBindArgs.put(Context.ALARM_SERVICE,
3037                    ServiceManager.getService(Context.ALARM_SERVICE));
3038        }
3039        return mAppBindArgs;
3040    }
3041
3042    /**
3043     * Update AMS states when an activity is resumed. This should only be called by
3044     * {@link ActivityStack#setResumedActivityLocked} when an activity is resumed.
3045     */
3046    void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
3047        if (r.task.isApplicationTask()) {
3048            if (mCurAppTimeTracker != r.appTimeTracker) {
3049                // We are switching app tracking.  Complete the current one.
3050                if (mCurAppTimeTracker != null) {
3051                    mCurAppTimeTracker.stop();
3052                    mHandler.obtainMessage(
3053                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
3054                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
3055                    mCurAppTimeTracker = null;
3056                }
3057                if (r.appTimeTracker != null) {
3058                    mCurAppTimeTracker = r.appTimeTracker;
3059                    startTimeTrackingFocusedActivityLocked();
3060                }
3061            } else {
3062                startTimeTrackingFocusedActivityLocked();
3063            }
3064        } else {
3065            r.appTimeTracker = null;
3066        }
3067        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3068        // TODO: Probably not, because we don't want to resume voice on switching
3069        // back to this activity
3070        if (r.task.voiceInteractor != null) {
3071            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
3072        } else {
3073            finishRunningVoiceLocked();
3074
3075            if (mLastResumedActivity != null) {
3076                final IVoiceInteractionSession session;
3077
3078                if (mLastResumedActivity.task != null
3079                        && mLastResumedActivity.task.voiceSession != null) {
3080                    session = mLastResumedActivity.task.voiceSession;
3081                } else {
3082                    session = mLastResumedActivity.voiceSession;
3083                }
3084
3085                if (session != null) {
3086                    // We had been in a voice interaction session, but now focused has
3087                    // move to something different.  Just finish the session, we can't
3088                    // return to it and retain the proper state and synchronization with
3089                    // the voice interaction service.
3090                    finishVoiceTask(session);
3091                }
3092            }
3093        }
3094
3095        mWindowManager.setFocusedApp(r.appToken, true);
3096
3097        applyUpdateLockStateLocked(r);
3098        applyUpdateVrModeLocked(r);
3099        if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
3100            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3101            mHandler.obtainMessage(
3102                    FOREGROUND_PROFILE_CHANGED_MSG, r.userId, 0).sendToTarget();
3103        }
3104
3105        mLastResumedActivity = r;
3106
3107        EventLogTags.writeAmSetResumedActivity(
3108                r == null ? -1 : r.userId,
3109                r == null ? "NULL" : r.shortComponentName,
3110                reason);
3111    }
3112
3113    @Override
3114    public void setFocusedStack(int stackId) {
3115        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3116        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3117        final long callingId = Binder.clearCallingIdentity();
3118        try {
3119            synchronized (this) {
3120                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3121                if (stack == null) {
3122                    return;
3123                }
3124                final ActivityRecord r = stack.topRunningActivityLocked();
3125                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
3126                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3127                }
3128            }
3129        } finally {
3130            Binder.restoreCallingIdentity(callingId);
3131        }
3132    }
3133
3134    @Override
3135    public void setFocusedTask(int taskId) {
3136        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3137        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3138        final long callingId = Binder.clearCallingIdentity();
3139        try {
3140            synchronized (this) {
3141                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3142                if (task == null) {
3143                    return;
3144                }
3145                final ActivityRecord r = task.topRunningActivityLocked();
3146                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
3147                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3148                }
3149            }
3150        } finally {
3151            Binder.restoreCallingIdentity(callingId);
3152        }
3153    }
3154
3155    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3156    @Override
3157    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3158        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3159        mTaskChangeNotificationController.registerTaskStackListener(listener);
3160    }
3161
3162    /**
3163     * Unregister a task stack listener so that it stops receiving callbacks.
3164     */
3165    @Override
3166    public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
3167         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "unregisterTaskStackListener()");
3168         mTaskChangeNotificationController.unregisterTaskStackListener(listener);
3169     }
3170
3171    @Override
3172    public void notifyActivityDrawn(IBinder token) {
3173        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3174        synchronized (this) {
3175            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3176            if (r != null) {
3177                r.getStack().notifyActivityDrawnLocked(r);
3178            }
3179        }
3180    }
3181
3182    final void applyUpdateLockStateLocked(ActivityRecord r) {
3183        // Modifications to the UpdateLock state are done on our handler, outside
3184        // the activity manager's locks.  The new state is determined based on the
3185        // state *now* of the relevant activity record.  The object is passed to
3186        // the handler solely for logging detail, not to be consulted/modified.
3187        final boolean nextState = r != null && r.immersive;
3188        mHandler.sendMessage(
3189                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3190    }
3191
3192    final void applyUpdateVrModeLocked(ActivityRecord r) {
3193        mHandler.sendMessage(
3194                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3195    }
3196
3197    private void sendNotifyVrManagerOfSleepState(boolean isSleeping) {
3198        mHandler.sendMessage(
3199                mHandler.obtainMessage(NOTIFY_VR_SLEEPING_MSG, isSleeping ? 1 : 0, 0));
3200    }
3201
3202    private void notifyVrManagerOfSleepState(boolean isSleeping) {
3203        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3204        if (vrService == null) {
3205            return;
3206        }
3207        vrService.onSleepStateChanged(isSleeping);
3208    }
3209
3210    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3211        Message msg = Message.obtain();
3212        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3213        msg.obj = r.task.askedCompatMode ? null : r;
3214        mUiHandler.sendMessage(msg);
3215    }
3216
3217    final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3218        final Configuration globalConfig = getGlobalConfiguration();
3219        if (globalConfig.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3220                && r.appInfo.requiresSmallestWidthDp > globalConfig.smallestScreenWidthDp) {
3221            final Message msg = Message.obtain();
3222            msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3223            msg.obj = r;
3224            mUiHandler.sendMessage(msg);
3225        }
3226    }
3227
3228    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3229            String what, Object obj, ProcessRecord srcApp) {
3230        app.lastActivityTime = now;
3231
3232        if (app.activities.size() > 0) {
3233            // Don't want to touch dependent processes that are hosting activities.
3234            return index;
3235        }
3236
3237        int lrui = mLruProcesses.lastIndexOf(app);
3238        if (lrui < 0) {
3239            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3240                    + what + " " + obj + " from " + srcApp);
3241            return index;
3242        }
3243
3244        if (lrui >= index) {
3245            // Don't want to cause this to move dependent processes *back* in the
3246            // list as if they were less frequently used.
3247            return index;
3248        }
3249
3250        if (lrui >= mLruProcessActivityStart) {
3251            // Don't want to touch dependent processes that are hosting activities.
3252            return index;
3253        }
3254
3255        mLruProcesses.remove(lrui);
3256        if (index > 0) {
3257            index--;
3258        }
3259        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3260                + " in LRU list: " + app);
3261        mLruProcesses.add(index, app);
3262        return index;
3263    }
3264
3265    static void killProcessGroup(int uid, int pid) {
3266        if (sKillHandler != null) {
3267            sKillHandler.sendMessage(
3268                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3269        } else {
3270            Slog.w(TAG, "Asked to kill process group before system bringup!");
3271            Process.killProcessGroup(uid, pid);
3272        }
3273    }
3274
3275    final void removeLruProcessLocked(ProcessRecord app) {
3276        int lrui = mLruProcesses.lastIndexOf(app);
3277        if (lrui >= 0) {
3278            if (!app.killed) {
3279                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3280                Process.killProcessQuiet(app.pid);
3281                killProcessGroup(app.uid, app.pid);
3282            }
3283            if (lrui <= mLruProcessActivityStart) {
3284                mLruProcessActivityStart--;
3285            }
3286            if (lrui <= mLruProcessServiceStart) {
3287                mLruProcessServiceStart--;
3288            }
3289            mLruProcesses.remove(lrui);
3290        }
3291    }
3292
3293    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3294            ProcessRecord client) {
3295        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3296                || app.treatLikeActivity;
3297        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3298        if (!activityChange && hasActivity) {
3299            // The process has activities, so we are only allowing activity-based adjustments
3300            // to move it.  It should be kept in the front of the list with other
3301            // processes that have activities, and we don't want those to change their
3302            // order except due to activity operations.
3303            return;
3304        }
3305
3306        mLruSeq++;
3307        final long now = SystemClock.uptimeMillis();
3308        app.lastActivityTime = now;
3309
3310        // First a quick reject: if the app is already at the position we will
3311        // put it, then there is nothing to do.
3312        if (hasActivity) {
3313            final int N = mLruProcesses.size();
3314            if (N > 0 && mLruProcesses.get(N-1) == app) {
3315                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3316                return;
3317            }
3318        } else {
3319            if (mLruProcessServiceStart > 0
3320                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3321                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3322                return;
3323            }
3324        }
3325
3326        int lrui = mLruProcesses.lastIndexOf(app);
3327
3328        if (app.persistent && lrui >= 0) {
3329            // We don't care about the position of persistent processes, as long as
3330            // they are in the list.
3331            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3332            return;
3333        }
3334
3335        /* In progress: compute new position first, so we can avoid doing work
3336           if the process is not actually going to move.  Not yet working.
3337        int addIndex;
3338        int nextIndex;
3339        boolean inActivity = false, inService = false;
3340        if (hasActivity) {
3341            // Process has activities, put it at the very tipsy-top.
3342            addIndex = mLruProcesses.size();
3343            nextIndex = mLruProcessServiceStart;
3344            inActivity = true;
3345        } else if (hasService) {
3346            // Process has services, put it at the top of the service list.
3347            addIndex = mLruProcessActivityStart;
3348            nextIndex = mLruProcessServiceStart;
3349            inActivity = true;
3350            inService = true;
3351        } else  {
3352            // Process not otherwise of interest, it goes to the top of the non-service area.
3353            addIndex = mLruProcessServiceStart;
3354            if (client != null) {
3355                int clientIndex = mLruProcesses.lastIndexOf(client);
3356                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3357                        + app);
3358                if (clientIndex >= 0 && addIndex > clientIndex) {
3359                    addIndex = clientIndex;
3360                }
3361            }
3362            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3363        }
3364
3365        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3366                + mLruProcessActivityStart + "): " + app);
3367        */
3368
3369        if (lrui >= 0) {
3370            if (lrui < mLruProcessActivityStart) {
3371                mLruProcessActivityStart--;
3372            }
3373            if (lrui < mLruProcessServiceStart) {
3374                mLruProcessServiceStart--;
3375            }
3376            /*
3377            if (addIndex > lrui) {
3378                addIndex--;
3379            }
3380            if (nextIndex > lrui) {
3381                nextIndex--;
3382            }
3383            */
3384            mLruProcesses.remove(lrui);
3385        }
3386
3387        /*
3388        mLruProcesses.add(addIndex, app);
3389        if (inActivity) {
3390            mLruProcessActivityStart++;
3391        }
3392        if (inService) {
3393            mLruProcessActivityStart++;
3394        }
3395        */
3396
3397        int nextIndex;
3398        if (hasActivity) {
3399            final int N = mLruProcesses.size();
3400            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3401                // Process doesn't have activities, but has clients with
3402                // activities...  move it up, but one below the top (the top
3403                // should always have a real activity).
3404                if (DEBUG_LRU) Slog.d(TAG_LRU,
3405                        "Adding to second-top of LRU activity list: " + app);
3406                mLruProcesses.add(N - 1, app);
3407                // To keep it from spamming the LRU list (by making a bunch of clients),
3408                // we will push down any other entries owned by the app.
3409                final int uid = app.info.uid;
3410                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3411                    ProcessRecord subProc = mLruProcesses.get(i);
3412                    if (subProc.info.uid == uid) {
3413                        // We want to push this one down the list.  If the process after
3414                        // it is for the same uid, however, don't do so, because we don't
3415                        // want them internally to be re-ordered.
3416                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3417                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3418                                    "Pushing uid " + uid + " swapping at " + i + ": "
3419                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3420                            ProcessRecord tmp = mLruProcesses.get(i);
3421                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3422                            mLruProcesses.set(i - 1, tmp);
3423                            i--;
3424                        }
3425                    } else {
3426                        // A gap, we can stop here.
3427                        break;
3428                    }
3429                }
3430            } else {
3431                // Process has activities, put it at the very tipsy-top.
3432                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3433                mLruProcesses.add(app);
3434            }
3435            nextIndex = mLruProcessServiceStart;
3436        } else if (hasService) {
3437            // Process has services, put it at the top of the service list.
3438            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3439            mLruProcesses.add(mLruProcessActivityStart, app);
3440            nextIndex = mLruProcessServiceStart;
3441            mLruProcessActivityStart++;
3442        } else  {
3443            // Process not otherwise of interest, it goes to the top of the non-service area.
3444            int index = mLruProcessServiceStart;
3445            if (client != null) {
3446                // If there is a client, don't allow the process to be moved up higher
3447                // in the list than that client.
3448                int clientIndex = mLruProcesses.lastIndexOf(client);
3449                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3450                        + " when updating " + app);
3451                if (clientIndex <= lrui) {
3452                    // Don't allow the client index restriction to push it down farther in the
3453                    // list than it already is.
3454                    clientIndex = lrui;
3455                }
3456                if (clientIndex >= 0 && index > clientIndex) {
3457                    index = clientIndex;
3458                }
3459            }
3460            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3461            mLruProcesses.add(index, app);
3462            nextIndex = index-1;
3463            mLruProcessActivityStart++;
3464            mLruProcessServiceStart++;
3465        }
3466
3467        // If the app is currently using a content provider or service,
3468        // bump those processes as well.
3469        for (int j=app.connections.size()-1; j>=0; j--) {
3470            ConnectionRecord cr = app.connections.valueAt(j);
3471            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3472                    && cr.binding.service.app != null
3473                    && cr.binding.service.app.lruSeq != mLruSeq
3474                    && !cr.binding.service.app.persistent) {
3475                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3476                        "service connection", cr, app);
3477            }
3478        }
3479        for (int j=app.conProviders.size()-1; j>=0; j--) {
3480            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3481            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3482                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3483                        "provider reference", cpr, app);
3484            }
3485        }
3486    }
3487
3488    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3489        if (uid == Process.SYSTEM_UID) {
3490            // The system gets to run in any process.  If there are multiple
3491            // processes with the same uid, just pick the first (this
3492            // should never happen).
3493            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3494            if (procs == null) return null;
3495            final int procCount = procs.size();
3496            for (int i = 0; i < procCount; i++) {
3497                final int procUid = procs.keyAt(i);
3498                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3499                    // Don't use an app process or different user process for system component.
3500                    continue;
3501                }
3502                return procs.valueAt(i);
3503            }
3504        }
3505        ProcessRecord proc = mProcessNames.get(processName, uid);
3506        if (false && proc != null && !keepIfLarge
3507                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3508                && proc.lastCachedPss >= 4000) {
3509            // Turn this condition on to cause killing to happen regularly, for testing.
3510            if (proc.baseProcessTracker != null) {
3511                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3512            }
3513            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3514        } else if (proc != null && !keepIfLarge
3515                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3516                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3517            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3518            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3519                if (proc.baseProcessTracker != null) {
3520                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3521                }
3522                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3523            }
3524        }
3525        return proc;
3526    }
3527
3528    void notifyPackageUse(String packageName, int reason) {
3529        IPackageManager pm = AppGlobals.getPackageManager();
3530        try {
3531            pm.notifyPackageUse(packageName, reason);
3532        } catch (RemoteException e) {
3533        }
3534    }
3535
3536    boolean isNextTransitionForward() {
3537        int transit = mWindowManager.getPendingAppTransition();
3538        return transit == TRANSIT_ACTIVITY_OPEN
3539                || transit == TRANSIT_TASK_OPEN
3540                || transit == TRANSIT_TASK_TO_FRONT;
3541    }
3542
3543    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3544            String processName, String abiOverride, int uid, Runnable crashHandler) {
3545        synchronized(this) {
3546            ApplicationInfo info = new ApplicationInfo();
3547            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3548            // For isolated processes, the former contains the parent's uid and the latter the
3549            // actual uid of the isolated process.
3550            // In the special case introduced by this method (which is, starting an isolated
3551            // process directly from the SystemServer without an actual parent app process) the
3552            // closest thing to a parent's uid is SYSTEM_UID.
3553            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3554            // the |isolated| logic in the ProcessRecord constructor.
3555            info.uid = Process.SYSTEM_UID;
3556            info.processName = processName;
3557            info.className = entryPoint;
3558            info.packageName = "android";
3559            info.seInfoUser = SELinuxUtil.COMPLETE_STR;
3560            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3561                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3562                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3563                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3564                    crashHandler);
3565            return proc != null ? proc.pid : 0;
3566        }
3567    }
3568
3569    final ProcessRecord startProcessLocked(String processName,
3570            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3571            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3572            boolean isolated, boolean keepIfLarge) {
3573        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3574                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3575                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3576                null /* crashHandler */);
3577    }
3578
3579    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3580            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3581            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3582            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3583        long startTime = SystemClock.elapsedRealtime();
3584        ProcessRecord app;
3585        if (!isolated) {
3586            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3587            checkTime(startTime, "startProcess: after getProcessRecord");
3588
3589            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3590                // If we are in the background, then check to see if this process
3591                // is bad.  If so, we will just silently fail.
3592                if (mAppErrors.isBadProcessLocked(info)) {
3593                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3594                            + "/" + info.processName);
3595                    return null;
3596                }
3597            } else {
3598                // When the user is explicitly starting a process, then clear its
3599                // crash count so that we won't make it bad until they see at
3600                // least one crash dialog again, and make the process good again
3601                // if it had been bad.
3602                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3603                        + "/" + info.processName);
3604                mAppErrors.resetProcessCrashTimeLocked(info);
3605                if (mAppErrors.isBadProcessLocked(info)) {
3606                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3607                            UserHandle.getUserId(info.uid), info.uid,
3608                            info.processName);
3609                    mAppErrors.clearBadProcessLocked(info);
3610                    if (app != null) {
3611                        app.bad = false;
3612                    }
3613                }
3614            }
3615        } else {
3616            // If this is an isolated process, it can't re-use an existing process.
3617            app = null;
3618        }
3619
3620        // We don't have to do anything more if:
3621        // (1) There is an existing application record; and
3622        // (2) The caller doesn't think it is dead, OR there is no thread
3623        //     object attached to it so we know it couldn't have crashed; and
3624        // (3) There is a pid assigned to it, so it is either starting or
3625        //     already running.
3626        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3627                + " app=" + app + " knownToBeDead=" + knownToBeDead
3628                + " thread=" + (app != null ? app.thread : null)
3629                + " pid=" + (app != null ? app.pid : -1));
3630        if (app != null && app.pid > 0) {
3631            if ((!knownToBeDead && !app.killed) || app.thread == null) {
3632                // We already have the app running, or are waiting for it to
3633                // come up (we have a pid but not yet its thread), so keep it.
3634                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3635                // If this is a new package in the process, add the package to the list
3636                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3637                checkTime(startTime, "startProcess: done, added package to proc");
3638                return app;
3639            }
3640
3641            // An application record is attached to a previous process,
3642            // clean it up now.
3643            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3644            checkTime(startTime, "startProcess: bad proc running, killing");
3645            killProcessGroup(app.uid, app.pid);
3646            handleAppDiedLocked(app, true, true);
3647            checkTime(startTime, "startProcess: done killing old proc");
3648        }
3649
3650        String hostingNameStr = hostingName != null
3651                ? hostingName.flattenToShortString() : null;
3652
3653        if (app == null) {
3654            checkTime(startTime, "startProcess: creating new process record");
3655            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3656            if (app == null) {
3657                Slog.w(TAG, "Failed making new process record for "
3658                        + processName + "/" + info.uid + " isolated=" + isolated);
3659                return null;
3660            }
3661            app.crashHandler = crashHandler;
3662            checkTime(startTime, "startProcess: done creating new process record");
3663        } else {
3664            // If this is a new package in the process, add the package to the list
3665            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3666            checkTime(startTime, "startProcess: added package to existing proc");
3667        }
3668
3669        // If the system is not ready yet, then hold off on starting this
3670        // process until it is.
3671        if (!mProcessesReady
3672                && !isAllowedWhileBooting(info)
3673                && !allowWhileBooting) {
3674            if (!mProcessesOnHold.contains(app)) {
3675                mProcessesOnHold.add(app);
3676            }
3677            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3678                    "System not ready, putting on hold: " + app);
3679            checkTime(startTime, "startProcess: returning with proc on hold");
3680            return app;
3681        }
3682
3683        checkTime(startTime, "startProcess: stepping in to startProcess");
3684        startProcessLocked(
3685                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3686        checkTime(startTime, "startProcess: done starting proc!");
3687        return (app.pid != 0) ? app : null;
3688    }
3689
3690    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3691        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3692    }
3693
3694    private final void startProcessLocked(ProcessRecord app,
3695            String hostingType, String hostingNameStr) {
3696        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3697                null /* entryPoint */, null /* entryPointArgs */);
3698    }
3699
3700    private final void startProcessLocked(ProcessRecord app, String hostingType,
3701            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3702        long startTime = SystemClock.elapsedRealtime();
3703        if (app.pid > 0 && app.pid != MY_PID) {
3704            checkTime(startTime, "startProcess: removing from pids map");
3705            synchronized (mPidsSelfLocked) {
3706                mPidsSelfLocked.remove(app.pid);
3707                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3708            }
3709            checkTime(startTime, "startProcess: done removing from pids map");
3710            app.setPid(0);
3711        }
3712
3713        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3714                "startProcessLocked removing on hold: " + app);
3715        mProcessesOnHold.remove(app);
3716
3717        checkTime(startTime, "startProcess: starting to update cpu stats");
3718        updateCpuStats();
3719        checkTime(startTime, "startProcess: done updating cpu stats");
3720
3721        try {
3722            try {
3723                final int userId = UserHandle.getUserId(app.uid);
3724                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3725            } catch (RemoteException e) {
3726                throw e.rethrowAsRuntimeException();
3727            }
3728
3729            int uid = app.uid;
3730            int[] gids = null;
3731            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3732            if (!app.isolated) {
3733                int[] permGids = null;
3734                try {
3735                    checkTime(startTime, "startProcess: getting gids from package manager");
3736                    final IPackageManager pm = AppGlobals.getPackageManager();
3737                    permGids = pm.getPackageGids(app.info.packageName,
3738                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3739                    StorageManagerInternal storageManagerInternal = LocalServices.getService(
3740                            StorageManagerInternal.class);
3741                    mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
3742                            app.info.packageName);
3743                } catch (RemoteException e) {
3744                    throw e.rethrowAsRuntimeException();
3745                }
3746
3747                /*
3748                 * Add shared application and profile GIDs so applications can share some
3749                 * resources like shared libraries and access user-wide resources
3750                 */
3751                if (ArrayUtils.isEmpty(permGids)) {
3752                    gids = new int[3];
3753                } else {
3754                    gids = new int[permGids.length + 3];
3755                    System.arraycopy(permGids, 0, gids, 3, permGids.length);
3756                }
3757                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3758                gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
3759                gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3760            }
3761            checkTime(startTime, "startProcess: building args");
3762            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3763                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3764                        && mTopComponent != null
3765                        && app.processName.equals(mTopComponent.getPackageName())) {
3766                    uid = 0;
3767                }
3768                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3769                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3770                    uid = 0;
3771                }
3772            }
3773            int debugFlags = 0;
3774            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3775                debugFlags |= Zygote.DEBUG_ENABLE_JDWP;
3776                debugFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
3777                // Also turn on CheckJNI for debuggable apps. It's quite
3778                // awkward to turn on otherwise.
3779                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3780            }
3781            // Run the app in safe mode if its manifest requests so or the
3782            // system is booted in safe mode.
3783            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3784                mSafeMode == true) {
3785                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3786            }
3787            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3788                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3789            }
3790            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3791            if ("true".equals(genDebugInfoProperty)) {
3792                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3793            }
3794            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3795                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3796            }
3797            if ("1".equals(SystemProperties.get("debug.assert"))) {
3798                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3799            }
3800            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3801                // Enable all debug flags required by the native debugger.
3802                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3803                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3804                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3805                mNativeDebuggingApp = null;
3806            }
3807
3808            String invokeWith = null;
3809            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3810                // Debuggable apps may include a wrapper script with their library directory.
3811                String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
3812                if (new File(wrapperFileName).exists()) {
3813                    invokeWith = "/system/bin/logwrapper " + wrapperFileName;
3814                }
3815            }
3816
3817            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3818            if (requiredAbi == null) {
3819                requiredAbi = Build.SUPPORTED_ABIS[0];
3820            }
3821
3822            String instructionSet = null;
3823            if (app.info.primaryCpuAbi != null) {
3824                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3825            }
3826
3827            app.gids = gids;
3828            app.requiredAbi = requiredAbi;
3829            app.instructionSet = instructionSet;
3830
3831            // the per-user SELinux context must be set
3832            if (TextUtils.isEmpty(app.info.seInfoUser)) {
3833                Slog.wtf(TAG, "SELinux tag not defined",
3834                        new IllegalStateException("SELinux tag not defined"));
3835            }
3836            final String seInfo = app.info.seInfo
3837                    + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
3838            // Start the process.  It will either succeed and return a result containing
3839            // the PID of the new process, or else throw a RuntimeException.
3840            boolean isActivityProcess = (entryPoint == null);
3841            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3842            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3843                    app.processName);
3844            checkTime(startTime, "startProcess: asking zygote to start proc");
3845            Process.ProcessStartResult startResult;
3846            if (hostingType.equals("webview_service")) {
3847                startResult = Process.startWebView(entryPoint,
3848                        app.processName, uid, uid, gids, debugFlags, mountExternal,
3849                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3850                        app.info.dataDir, null, entryPointArgs);
3851            } else {
3852                startResult = Process.start(entryPoint,
3853                        app.processName, uid, uid, gids, debugFlags, mountExternal,
3854                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3855                        app.info.dataDir, invokeWith, entryPointArgs);
3856            }
3857            checkTime(startTime, "startProcess: returned from zygote!");
3858            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3859
3860            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3861            checkTime(startTime, "startProcess: done updating battery stats");
3862
3863            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3864                    UserHandle.getUserId(uid), startResult.pid, uid,
3865                    app.processName, hostingType,
3866                    hostingNameStr != null ? hostingNameStr : "");
3867
3868            try {
3869                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3870                        seInfo, app.info.sourceDir, startResult.pid);
3871            } catch (RemoteException ex) {
3872                // Ignore
3873            }
3874
3875            if (app.persistent) {
3876                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3877            }
3878
3879            checkTime(startTime, "startProcess: building log message");
3880            StringBuilder buf = mStringBuilder;
3881            buf.setLength(0);
3882            buf.append("Start proc ");
3883            buf.append(startResult.pid);
3884            buf.append(':');
3885            buf.append(app.processName);
3886            buf.append('/');
3887            UserHandle.formatUid(buf, uid);
3888            if (!isActivityProcess) {
3889                buf.append(" [");
3890                buf.append(entryPoint);
3891                buf.append("]");
3892            }
3893            buf.append(" for ");
3894            buf.append(hostingType);
3895            if (hostingNameStr != null) {
3896                buf.append(" ");
3897                buf.append(hostingNameStr);
3898            }
3899            Slog.i(TAG, buf.toString());
3900            app.setPid(startResult.pid);
3901            app.usingWrapper = startResult.usingWrapper;
3902            app.removed = false;
3903            app.killed = false;
3904            app.killedByAm = false;
3905            checkTime(startTime, "startProcess: starting to update pids map");
3906            ProcessRecord oldApp;
3907            synchronized (mPidsSelfLocked) {
3908                oldApp = mPidsSelfLocked.get(startResult.pid);
3909            }
3910            // If there is already an app occupying that pid that hasn't been cleaned up
3911            if (oldApp != null && !app.isolated) {
3912                // Clean up anything relating to this pid first
3913                Slog.w(TAG, "Reusing pid " + startResult.pid
3914                        + " while app is still mapped to it");
3915                cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3916                        true /*replacingPid*/);
3917            }
3918            synchronized (mPidsSelfLocked) {
3919                this.mPidsSelfLocked.put(startResult.pid, app);
3920                if (isActivityProcess) {
3921                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3922                    msg.obj = app;
3923                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3924                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3925                }
3926            }
3927            checkTime(startTime, "startProcess: done updating pids map");
3928        } catch (RuntimeException e) {
3929            Slog.e(TAG, "Failure starting process " + app.processName, e);
3930
3931            // Something went very wrong while trying to start this process; one
3932            // common case is when the package is frozen due to an active
3933            // upgrade. To recover, clean up any active bookkeeping related to
3934            // starting this process. (We already invoked this method once when
3935            // the package was initially frozen through KILL_APPLICATION_MSG, so
3936            // it doesn't hurt to use it again.)
3937            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3938                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3939        }
3940    }
3941
3942    void updateUsageStats(ActivityRecord component, boolean resumed) {
3943        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3944                "updateUsageStats: comp=" + component + "res=" + resumed);
3945        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3946        if (resumed) {
3947            if (mUsageStatsService != null) {
3948                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3949                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3950            }
3951            synchronized (stats) {
3952                stats.noteActivityResumedLocked(component.app.uid);
3953            }
3954        } else {
3955            if (mUsageStatsService != null) {
3956                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3957                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3958            }
3959            synchronized (stats) {
3960                stats.noteActivityPausedLocked(component.app.uid);
3961            }
3962        }
3963    }
3964
3965    Intent getHomeIntent() {
3966        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3967        intent.setComponent(mTopComponent);
3968        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3969        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3970            intent.addCategory(Intent.CATEGORY_HOME);
3971        }
3972        return intent;
3973    }
3974
3975    boolean startHomeActivityLocked(int userId, String reason) {
3976        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3977                && mTopAction == null) {
3978            // We are running in factory test mode, but unable to find
3979            // the factory test app, so just sit around displaying the
3980            // error message and don't try to start anything.
3981            return false;
3982        }
3983        Intent intent = getHomeIntent();
3984        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3985        if (aInfo != null) {
3986            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3987            // Don't do this if the home app is currently being
3988            // instrumented.
3989            aInfo = new ActivityInfo(aInfo);
3990            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3991            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3992                    aInfo.applicationInfo.uid, true);
3993            if (app == null || app.instr == null) {
3994                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3995                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3996            }
3997        } else {
3998            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3999        }
4000
4001        return true;
4002    }
4003
4004    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
4005        ActivityInfo ai = null;
4006        ComponentName comp = intent.getComponent();
4007        try {
4008            if (comp != null) {
4009                // Factory test.
4010                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
4011            } else {
4012                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
4013                        intent,
4014                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
4015                        flags, userId);
4016
4017                if (info != null) {
4018                    ai = info.activityInfo;
4019                }
4020            }
4021        } catch (RemoteException e) {
4022            // ignore
4023        }
4024
4025        return ai;
4026    }
4027
4028    /**
4029     * Starts the "new version setup screen" if appropriate.
4030     */
4031    void startSetupActivityLocked() {
4032        // Only do this once per boot.
4033        if (mCheckedForSetup) {
4034            return;
4035        }
4036
4037        // We will show this screen if the current one is a different
4038        // version than the last one shown, and we are not running in
4039        // low-level factory test mode.
4040        final ContentResolver resolver = mContext.getContentResolver();
4041        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
4042                Settings.Global.getInt(resolver,
4043                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
4044            mCheckedForSetup = true;
4045
4046            // See if we should be showing the platform update setup UI.
4047            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
4048            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
4049                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
4050            if (!ris.isEmpty()) {
4051                final ResolveInfo ri = ris.get(0);
4052                String vers = ri.activityInfo.metaData != null
4053                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
4054                        : null;
4055                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
4056                    vers = ri.activityInfo.applicationInfo.metaData.getString(
4057                            Intent.METADATA_SETUP_VERSION);
4058                }
4059                String lastVers = Settings.Secure.getString(
4060                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
4061                if (vers != null && !vers.equals(lastVers)) {
4062                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4063                    intent.setComponent(new ComponentName(
4064                            ri.activityInfo.packageName, ri.activityInfo.name));
4065                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
4066                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
4067                            null, 0, 0, 0, null, false, false, null, null, null);
4068                }
4069            }
4070        }
4071    }
4072
4073    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4074        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4075    }
4076
4077    void enforceNotIsolatedCaller(String caller) {
4078        if (UserHandle.isIsolated(Binder.getCallingUid())) {
4079            throw new SecurityException("Isolated process not allowed to call " + caller);
4080        }
4081    }
4082
4083    void enforceShellRestriction(String restriction, int userHandle) {
4084        if (Binder.getCallingUid() == Process.SHELL_UID) {
4085            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
4086                throw new SecurityException("Shell does not have permission to access user "
4087                        + userHandle);
4088            }
4089        }
4090    }
4091
4092    @Override
4093    public int getFrontActivityScreenCompatMode() {
4094        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4095        synchronized (this) {
4096            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4097        }
4098    }
4099
4100    @Override
4101    public void setFrontActivityScreenCompatMode(int mode) {
4102        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4103                "setFrontActivityScreenCompatMode");
4104        synchronized (this) {
4105            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4106        }
4107    }
4108
4109    @Override
4110    public int getPackageScreenCompatMode(String packageName) {
4111        enforceNotIsolatedCaller("getPackageScreenCompatMode");
4112        synchronized (this) {
4113            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4114        }
4115    }
4116
4117    @Override
4118    public void setPackageScreenCompatMode(String packageName, int mode) {
4119        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4120                "setPackageScreenCompatMode");
4121        synchronized (this) {
4122            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4123        }
4124    }
4125
4126    @Override
4127    public boolean getPackageAskScreenCompat(String packageName) {
4128        enforceNotIsolatedCaller("getPackageAskScreenCompat");
4129        synchronized (this) {
4130            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4131        }
4132    }
4133
4134    @Override
4135    public void setPackageAskScreenCompat(String packageName, boolean ask) {
4136        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4137                "setPackageAskScreenCompat");
4138        synchronized (this) {
4139            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4140        }
4141    }
4142
4143    private boolean hasUsageStatsPermission(String callingPackage) {
4144        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4145                Binder.getCallingUid(), callingPackage);
4146        if (mode == AppOpsManager.MODE_DEFAULT) {
4147            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4148                    == PackageManager.PERMISSION_GRANTED;
4149        }
4150        return mode == AppOpsManager.MODE_ALLOWED;
4151    }
4152
4153    @Override
4154    public int getPackageProcessState(String packageName, String callingPackage) {
4155        if (!hasUsageStatsPermission(callingPackage)) {
4156            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
4157                    "getPackageProcessState");
4158        }
4159
4160        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4161        synchronized (this) {
4162            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4163                final ProcessRecord proc = mLruProcesses.get(i);
4164                if (procState > proc.setProcState) {
4165                    if (proc.pkgList.containsKey(packageName) ||
4166                            (proc.pkgDeps != null && proc.pkgDeps.contains(packageName))) {
4167                        procState = proc.setProcState;
4168                    }
4169                }
4170            }
4171        }
4172        return procState;
4173    }
4174
4175    @Override
4176    public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4177            throws RemoteException {
4178        synchronized (this) {
4179            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4180            if (app == null) {
4181                throw new IllegalArgumentException("Unknown process: " + process);
4182            }
4183            if (app.thread == null) {
4184                throw new IllegalArgumentException("Process has no app thread");
4185            }
4186            if (app.trimMemoryLevel >= level) {
4187                throw new IllegalArgumentException(
4188                        "Unable to set a higher trim level than current level");
4189            }
4190            if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4191                    app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4192                throw new IllegalArgumentException("Unable to set a background trim level "
4193                    + "on a foreground process");
4194            }
4195            app.thread.scheduleTrimMemory(level);
4196            app.trimMemoryLevel = level;
4197            return true;
4198        }
4199    }
4200
4201    private void dispatchProcessesChanged() {
4202        int N;
4203        synchronized (this) {
4204            N = mPendingProcessChanges.size();
4205            if (mActiveProcessChanges.length < N) {
4206                mActiveProcessChanges = new ProcessChangeItem[N];
4207            }
4208            mPendingProcessChanges.toArray(mActiveProcessChanges);
4209            mPendingProcessChanges.clear();
4210            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4211                    "*** Delivering " + N + " process changes");
4212        }
4213
4214        int i = mProcessObservers.beginBroadcast();
4215        while (i > 0) {
4216            i--;
4217            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4218            if (observer != null) {
4219                try {
4220                    for (int j=0; j<N; j++) {
4221                        ProcessChangeItem item = mActiveProcessChanges[j];
4222                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4223                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4224                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4225                                    + item.uid + ": " + item.foregroundActivities);
4226                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4227                                    item.foregroundActivities);
4228                        }
4229                    }
4230                } catch (RemoteException e) {
4231                }
4232            }
4233        }
4234        mProcessObservers.finishBroadcast();
4235
4236        synchronized (this) {
4237            for (int j=0; j<N; j++) {
4238                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4239            }
4240        }
4241    }
4242
4243    private void dispatchProcessDied(int pid, int uid) {
4244        int i = mProcessObservers.beginBroadcast();
4245        while (i > 0) {
4246            i--;
4247            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4248            if (observer != null) {
4249                try {
4250                    observer.onProcessDied(pid, uid);
4251                } catch (RemoteException e) {
4252                }
4253            }
4254        }
4255        mProcessObservers.finishBroadcast();
4256    }
4257
4258    private void dispatchUidsChanged() {
4259        int N;
4260        synchronized (this) {
4261            N = mPendingUidChanges.size();
4262            if (mActiveUidChanges.length < N) {
4263                mActiveUidChanges = new UidRecord.ChangeItem[N];
4264            }
4265            for (int i=0; i<N; i++) {
4266                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4267                mActiveUidChanges[i] = change;
4268                if (change.uidRecord != null) {
4269                    change.uidRecord.pendingChange = null;
4270                    change.uidRecord = null;
4271                }
4272            }
4273            mPendingUidChanges.clear();
4274            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4275                    "*** Delivering " + N + " uid changes");
4276        }
4277
4278        int i = mUidObservers.beginBroadcast();
4279        while (i > 0) {
4280            i--;
4281            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4282            final UidObserverRegistration reg = (UidObserverRegistration)
4283                    mUidObservers.getBroadcastCookie(i);
4284            if (observer != null) {
4285                try {
4286                    for (int j=0; j<N; j++) {
4287                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4288                        final int change = item.change;
4289                        UidRecord validateUid = null;
4290                        if (VALIDATE_UID_STATES && i == 0) {
4291                            validateUid = mValidateUids.get(item.uid);
4292                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4293                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4294                                validateUid = new UidRecord(item.uid);
4295                                mValidateUids.put(item.uid, validateUid);
4296                            }
4297                        }
4298                        if (change == UidRecord.CHANGE_IDLE
4299                                || change == UidRecord.CHANGE_GONE_IDLE) {
4300                            if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4301                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4302                                        "UID idle uid=" + item.uid);
4303                                observer.onUidIdle(item.uid, item.ephemeral);
4304                            }
4305                            if (VALIDATE_UID_STATES && i == 0) {
4306                                if (validateUid != null) {
4307                                    validateUid.idle = true;
4308                                }
4309                            }
4310                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4311                            if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4312                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4313                                        "UID active uid=" + item.uid);
4314                                observer.onUidActive(item.uid);
4315                            }
4316                            if (VALIDATE_UID_STATES && i == 0) {
4317                                validateUid.idle = false;
4318                            }
4319                        }
4320                        if (change == UidRecord.CHANGE_GONE
4321                                || change == UidRecord.CHANGE_GONE_IDLE) {
4322                            if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4323                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4324                                        "UID gone uid=" + item.uid);
4325                                observer.onUidGone(item.uid, item.ephemeral);
4326                            }
4327                            if (reg.lastProcStates != null) {
4328                                reg.lastProcStates.delete(item.uid);
4329                            }
4330                            if (VALIDATE_UID_STATES && i == 0) {
4331                                if (validateUid != null) {
4332                                    mValidateUids.remove(item.uid);
4333                                }
4334                            }
4335                        } else {
4336                            if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4337                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4338                                        "UID CHANGED uid=" + item.uid
4339                                                + ": " + item.processState);
4340                                boolean doReport = true;
4341                                if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
4342                                    final int lastState = reg.lastProcStates.get(item.uid,
4343                                            ActivityManager.PROCESS_STATE_UNKNOWN);
4344                                    if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
4345                                        final boolean lastAboveCut = lastState <= reg.cutpoint;
4346                                        final boolean newAboveCut = item.processState <= reg.cutpoint;
4347                                        doReport = lastAboveCut != newAboveCut;
4348                                    } else {
4349                                        doReport = item.processState
4350                                                != ActivityManager.PROCESS_STATE_NONEXISTENT;
4351                                    }
4352                                }
4353                                if (doReport) {
4354                                    if (reg.lastProcStates != null) {
4355                                        reg.lastProcStates.put(item.uid, item.processState);
4356                                    }
4357                                    observer.onUidStateChanged(item.uid, item.processState);
4358                                }
4359                            }
4360                            if (VALIDATE_UID_STATES && i == 0) {
4361                                validateUid.curProcState = validateUid.setProcState
4362                                        = item.processState;
4363                            }
4364                        }
4365                    }
4366                } catch (RemoteException e) {
4367                }
4368            }
4369        }
4370        mUidObservers.finishBroadcast();
4371
4372        synchronized (this) {
4373            for (int j=0; j<N; j++) {
4374                mAvailUidChanges.add(mActiveUidChanges[j]);
4375            }
4376        }
4377    }
4378
4379    @Override
4380    public final int startActivity(IApplicationThread caller, String callingPackage,
4381            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4382            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4383        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4384                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4385                UserHandle.getCallingUserId());
4386    }
4387
4388    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4389        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4390        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4391                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4392                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4393
4394        // TODO: Switch to user app stacks here.
4395        String mimeType = intent.getType();
4396        final Uri data = intent.getData();
4397        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4398            mimeType = getProviderMimeType(data, userId);
4399        }
4400        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4401
4402        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4403        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4404                null, 0, 0, null, null, null, null, false, userId, container, null);
4405    }
4406
4407    @Override
4408    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4409            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4410            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4411        enforceNotIsolatedCaller("startActivity");
4412        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4413                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4414        // TODO: Switch to user app stacks here.
4415        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4416                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4417                profilerInfo, null, null, bOptions, false, userId, null, null);
4418    }
4419
4420    @Override
4421    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4422            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4423            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4424            int userId) {
4425
4426        // This is very dangerous -- it allows you to perform a start activity (including
4427        // permission grants) as any app that may launch one of your own activities.  So
4428        // we will only allow this to be done from activities that are part of the core framework,
4429        // and then only when they are running as the system.
4430        final ActivityRecord sourceRecord;
4431        final int targetUid;
4432        final String targetPackage;
4433        synchronized (this) {
4434            if (resultTo == null) {
4435                throw new SecurityException("Must be called from an activity");
4436            }
4437            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4438            if (sourceRecord == null) {
4439                throw new SecurityException("Called with bad activity token: " + resultTo);
4440            }
4441            if (!sourceRecord.info.packageName.equals("android")) {
4442                throw new SecurityException(
4443                        "Must be called from an activity that is declared in the android package");
4444            }
4445            if (sourceRecord.app == null) {
4446                throw new SecurityException("Called without a process attached to activity");
4447            }
4448            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4449                // This is still okay, as long as this activity is running under the
4450                // uid of the original calling activity.
4451                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4452                    throw new SecurityException(
4453                            "Calling activity in uid " + sourceRecord.app.uid
4454                                    + " must be system uid or original calling uid "
4455                                    + sourceRecord.launchedFromUid);
4456                }
4457            }
4458            if (ignoreTargetSecurity) {
4459                if (intent.getComponent() == null) {
4460                    throw new SecurityException(
4461                            "Component must be specified with ignoreTargetSecurity");
4462                }
4463                if (intent.getSelector() != null) {
4464                    throw new SecurityException(
4465                            "Selector not allowed with ignoreTargetSecurity");
4466                }
4467            }
4468            targetUid = sourceRecord.launchedFromUid;
4469            targetPackage = sourceRecord.launchedFromPackage;
4470        }
4471
4472        if (userId == UserHandle.USER_NULL) {
4473            userId = UserHandle.getUserId(sourceRecord.app.uid);
4474        }
4475
4476        // TODO: Switch to user app stacks here.
4477        try {
4478            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4479                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4480                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4481            return ret;
4482        } catch (SecurityException e) {
4483            // XXX need to figure out how to propagate to original app.
4484            // A SecurityException here is generally actually a fault of the original
4485            // calling activity (such as a fairly granting permissions), so propagate it
4486            // back to them.
4487            /*
4488            StringBuilder msg = new StringBuilder();
4489            msg.append("While launching");
4490            msg.append(intent.toString());
4491            msg.append(": ");
4492            msg.append(e.getMessage());
4493            */
4494            throw e;
4495        }
4496    }
4497
4498    @Override
4499    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4500            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4501            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4502        enforceNotIsolatedCaller("startActivityAndWait");
4503        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4504                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4505        WaitResult res = new WaitResult();
4506        // TODO: Switch to user app stacks here.
4507        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4508                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4509                bOptions, false, userId, null, null);
4510        return res;
4511    }
4512
4513    @Override
4514    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4515            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4516            int startFlags, Configuration config, Bundle bOptions, int userId) {
4517        enforceNotIsolatedCaller("startActivityWithConfig");
4518        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4519                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4520        // TODO: Switch to user app stacks here.
4521        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4522                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4523                null, null, config, bOptions, false, userId, null, null);
4524        return ret;
4525    }
4526
4527    @Override
4528    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4529            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4530            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4531            throws TransactionTooLargeException {
4532        enforceNotIsolatedCaller("startActivityIntentSender");
4533        // Refuse possible leaked file descriptors
4534        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4535            throw new IllegalArgumentException("File descriptors passed in Intent");
4536        }
4537
4538        IIntentSender sender = intent.getTarget();
4539        if (!(sender instanceof PendingIntentRecord)) {
4540            throw new IllegalArgumentException("Bad PendingIntent object");
4541        }
4542
4543        PendingIntentRecord pir = (PendingIntentRecord)sender;
4544
4545        synchronized (this) {
4546            // If this is coming from the currently resumed activity, it is
4547            // effectively saying that app switches are allowed at this point.
4548            final ActivityStack stack = getFocusedStack();
4549            if (stack.mResumedActivity != null &&
4550                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4551                mAppSwitchesAllowedTime = 0;
4552            }
4553        }
4554        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4555                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4556        return ret;
4557    }
4558
4559    @Override
4560    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4561            Intent intent, String resolvedType, IVoiceInteractionSession session,
4562            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4563            Bundle bOptions, int userId) {
4564        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4565                != PackageManager.PERMISSION_GRANTED) {
4566            String msg = "Permission Denial: startVoiceActivity() from pid="
4567                    + Binder.getCallingPid()
4568                    + ", uid=" + Binder.getCallingUid()
4569                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4570            Slog.w(TAG, msg);
4571            throw new SecurityException(msg);
4572        }
4573        if (session == null || interactor == null) {
4574            throw new NullPointerException("null session or interactor");
4575        }
4576        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4577                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4578        // TODO: Switch to user app stacks here.
4579        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4580                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4581                null, bOptions, false, userId, null, null);
4582    }
4583
4584    @Override
4585    public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
4586            Intent intent, String resolvedType, Bundle bOptions, int userId) {
4587        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4588                != PackageManager.PERMISSION_GRANTED) {
4589            final String msg = "Permission Denial: startAssistantActivity() from pid="
4590                    + Binder.getCallingPid()
4591                    + ", uid=" + Binder.getCallingUid()
4592                    + " requires " + Manifest.permission.BIND_VOICE_INTERACTION;
4593            Slog.w(TAG, msg);
4594            throw new SecurityException(msg);
4595        }
4596        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4597                ALLOW_FULL_ONLY, "startAssistantActivity", null);
4598        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4599                resolvedType, null, null, null, null, 0, 0, null, null, null, bOptions, false,
4600                userId, null, null);
4601    }
4602
4603    @Override
4604    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4605            throws RemoteException {
4606        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4607        synchronized (this) {
4608            ActivityRecord activity = getFocusedStack().topActivity();
4609            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4610                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4611            }
4612            if (mRunningVoice != null || activity.task.voiceSession != null
4613                    || activity.voiceSession != null) {
4614                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4615                return;
4616            }
4617            if (activity.pendingVoiceInteractionStart) {
4618                Slog.w(TAG, "Pending start of voice interaction already.");
4619                return;
4620            }
4621            activity.pendingVoiceInteractionStart = true;
4622        }
4623        LocalServices.getService(VoiceInteractionManagerInternal.class)
4624                .startLocalVoiceInteraction(callingActivity, options);
4625    }
4626
4627    @Override
4628    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4629        LocalServices.getService(VoiceInteractionManagerInternal.class)
4630                .stopLocalVoiceInteraction(callingActivity);
4631    }
4632
4633    @Override
4634    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4635        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4636                .supportsLocalVoiceInteraction();
4637    }
4638
4639    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4640            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4641        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4642        if (activityToCallback == null) return;
4643        activityToCallback.setVoiceSessionLocked(voiceSession);
4644
4645        // Inform the activity
4646        try {
4647            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4648                    voiceInteractor);
4649            long token = Binder.clearCallingIdentity();
4650            try {
4651                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4652            } finally {
4653                Binder.restoreCallingIdentity(token);
4654            }
4655            // TODO: VI Should we cache the activity so that it's easier to find later
4656            // rather than scan through all the stacks and activities?
4657        } catch (RemoteException re) {
4658            activityToCallback.clearVoiceSessionLocked();
4659            // TODO: VI Should this terminate the voice session?
4660        }
4661    }
4662
4663    @Override
4664    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4665        synchronized (this) {
4666            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4667                if (keepAwake) {
4668                    mVoiceWakeLock.acquire();
4669                } else {
4670                    mVoiceWakeLock.release();
4671                }
4672            }
4673        }
4674    }
4675
4676    @Override
4677    public boolean startNextMatchingActivity(IBinder callingActivity,
4678            Intent intent, Bundle bOptions) {
4679        // Refuse possible leaked file descriptors
4680        if (intent != null && intent.hasFileDescriptors() == true) {
4681            throw new IllegalArgumentException("File descriptors passed in Intent");
4682        }
4683        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4684
4685        synchronized (this) {
4686            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4687            if (r == null) {
4688                ActivityOptions.abort(options);
4689                return false;
4690            }
4691            if (r.app == null || r.app.thread == null) {
4692                // The caller is not running...  d'oh!
4693                ActivityOptions.abort(options);
4694                return false;
4695            }
4696            intent = new Intent(intent);
4697            // The caller is not allowed to change the data.
4698            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4699            // And we are resetting to find the next component...
4700            intent.setComponent(null);
4701
4702            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4703
4704            ActivityInfo aInfo = null;
4705            try {
4706                List<ResolveInfo> resolves =
4707                    AppGlobals.getPackageManager().queryIntentActivities(
4708                            intent, r.resolvedType,
4709                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4710                            UserHandle.getCallingUserId()).getList();
4711
4712                // Look for the original activity in the list...
4713                final int N = resolves != null ? resolves.size() : 0;
4714                for (int i=0; i<N; i++) {
4715                    ResolveInfo rInfo = resolves.get(i);
4716                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4717                            && rInfo.activityInfo.name.equals(r.info.name)) {
4718                        // We found the current one...  the next matching is
4719                        // after it.
4720                        i++;
4721                        if (i<N) {
4722                            aInfo = resolves.get(i).activityInfo;
4723                        }
4724                        if (debug) {
4725                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4726                                    + "/" + r.info.name);
4727                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4728                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4729                        }
4730                        break;
4731                    }
4732                }
4733            } catch (RemoteException e) {
4734            }
4735
4736            if (aInfo == null) {
4737                // Nobody who is next!
4738                ActivityOptions.abort(options);
4739                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4740                return false;
4741            }
4742
4743            intent.setComponent(new ComponentName(
4744                    aInfo.applicationInfo.packageName, aInfo.name));
4745            intent.setFlags(intent.getFlags()&~(
4746                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4747                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4748                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4749                    Intent.FLAG_ACTIVITY_NEW_TASK));
4750
4751            // Okay now we need to start the new activity, replacing the
4752            // currently running activity.  This is a little tricky because
4753            // we want to start the new one as if the current one is finished,
4754            // but not finish the current one first so that there is no flicker.
4755            // And thus...
4756            final boolean wasFinishing = r.finishing;
4757            r.finishing = true;
4758
4759            // Propagate reply information over to the new activity.
4760            final ActivityRecord resultTo = r.resultTo;
4761            final String resultWho = r.resultWho;
4762            final int requestCode = r.requestCode;
4763            r.resultTo = null;
4764            if (resultTo != null) {
4765                resultTo.removeResultsLocked(r, resultWho, requestCode);
4766            }
4767
4768            final long origId = Binder.clearCallingIdentity();
4769            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4770                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4771                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4772                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4773                    false, false, null, null, null);
4774            Binder.restoreCallingIdentity(origId);
4775
4776            r.finishing = wasFinishing;
4777            if (res != ActivityManager.START_SUCCESS) {
4778                return false;
4779            }
4780            return true;
4781        }
4782    }
4783
4784    @Override
4785    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4786        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4787            String msg = "Permission Denial: startActivityFromRecents called without " +
4788                    START_TASKS_FROM_RECENTS;
4789            Slog.w(TAG, msg);
4790            throw new SecurityException(msg);
4791        }
4792        final long origId = Binder.clearCallingIdentity();
4793        try {
4794            synchronized (this) {
4795                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4796            }
4797        } finally {
4798            Binder.restoreCallingIdentity(origId);
4799        }
4800    }
4801
4802    final int startActivityInPackage(int uid, String callingPackage,
4803            Intent intent, String resolvedType, IBinder resultTo,
4804            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4805            IActivityContainer container, TaskRecord inTask) {
4806
4807        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4808                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4809
4810        // TODO: Switch to user app stacks here.
4811        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4812                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4813                null, null, null, bOptions, false, userId, container, inTask);
4814        return ret;
4815    }
4816
4817    @Override
4818    public final int startActivities(IApplicationThread caller, String callingPackage,
4819            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4820            int userId) {
4821        enforceNotIsolatedCaller("startActivities");
4822        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4823                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4824        // TODO: Switch to user app stacks here.
4825        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4826                resolvedTypes, resultTo, bOptions, userId);
4827        return ret;
4828    }
4829
4830    final int startActivitiesInPackage(int uid, String callingPackage,
4831            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4832            Bundle bOptions, int userId) {
4833
4834        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4835                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4836        // TODO: Switch to user app stacks here.
4837        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4838                resultTo, bOptions, userId);
4839        return ret;
4840    }
4841
4842    @Override
4843    public void reportActivityFullyDrawn(IBinder token) {
4844        synchronized (this) {
4845            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4846            if (r == null) {
4847                return;
4848            }
4849            r.reportFullyDrawnLocked();
4850        }
4851    }
4852
4853    @Override
4854    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4855        synchronized (this) {
4856            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4857            if (r == null) {
4858                return;
4859            }
4860            final long origId = Binder.clearCallingIdentity();
4861            try {
4862                r.setRequestedOrientation(requestedOrientation);
4863            } finally {
4864                Binder.restoreCallingIdentity(origId);
4865            }
4866        }
4867    }
4868
4869    @Override
4870    public int getRequestedOrientation(IBinder token) {
4871        synchronized (this) {
4872            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4873            if (r == null) {
4874                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4875            }
4876            return r.getRequestedOrientation();
4877        }
4878    }
4879
4880    @Override
4881    public final void requestActivityRelaunch(IBinder token) {
4882        synchronized(this) {
4883            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4884            if (r == null) {
4885                return;
4886            }
4887            final long origId = Binder.clearCallingIdentity();
4888            try {
4889                r.forceNewConfig = true;
4890                r.ensureActivityConfigurationLocked(0 /* globalChanges */,
4891                        false /* preserveWindow */);
4892            } finally {
4893                Binder.restoreCallingIdentity(origId);
4894            }
4895        }
4896    }
4897
4898    /**
4899     * This is the internal entry point for handling Activity.finish().
4900     *
4901     * @param token The Binder token referencing the Activity we want to finish.
4902     * @param resultCode Result code, if any, from this Activity.
4903     * @param resultData Result data (Intent), if any, from this Activity.
4904     * @param finishTask Whether to finish the task associated with this Activity.
4905     *
4906     * @return Returns true if the activity successfully finished, or false if it is still running.
4907     */
4908    @Override
4909    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4910            int finishTask) {
4911        // Refuse possible leaked file descriptors
4912        if (resultData != null && resultData.hasFileDescriptors() == true) {
4913            throw new IllegalArgumentException("File descriptors passed in Intent");
4914        }
4915
4916        synchronized(this) {
4917            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4918            if (r == null) {
4919                return true;
4920            }
4921            // Keep track of the root activity of the task before we finish it
4922            TaskRecord tr = r.task;
4923            ActivityRecord rootR = tr.getRootActivity();
4924            if (rootR == null) {
4925                Slog.w(TAG, "Finishing task with all activities already finished");
4926            }
4927            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4928            // finish.
4929            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4930                    mStackSupervisor.isLastLockedTask(tr)) {
4931                Slog.i(TAG, "Not finishing task in lock task mode");
4932                mStackSupervisor.showLockTaskToast();
4933                return false;
4934            }
4935            if (mController != null) {
4936                // Find the first activity that is not finishing.
4937                ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
4938                if (next != null) {
4939                    // ask watcher if this is allowed
4940                    boolean resumeOK = true;
4941                    try {
4942                        resumeOK = mController.activityResuming(next.packageName);
4943                    } catch (RemoteException e) {
4944                        mController = null;
4945                        Watchdog.getInstance().setActivityController(null);
4946                    }
4947
4948                    if (!resumeOK) {
4949                        Slog.i(TAG, "Not finishing activity because controller resumed");
4950                        return false;
4951                    }
4952                }
4953            }
4954            final long origId = Binder.clearCallingIdentity();
4955            try {
4956                boolean res;
4957                final boolean finishWithRootActivity =
4958                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4959                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4960                        || (finishWithRootActivity && r == rootR)) {
4961                    // If requested, remove the task that is associated to this activity only if it
4962                    // was the root activity in the task. The result code and data is ignored
4963                    // because we don't support returning them across task boundaries. Also, to
4964                    // keep backwards compatibility we remove the task from recents when finishing
4965                    // task with root activity.
4966                    res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4967                    if (!res) {
4968                        Slog.i(TAG, "Removing task failed to finish activity");
4969                    }
4970                } else {
4971                    res = tr.getStack().requestFinishActivityLocked(token, resultCode,
4972                            resultData, "app-request", true);
4973                    if (!res) {
4974                        Slog.i(TAG, "Failed to finish by app-request");
4975                    }
4976                }
4977                return res;
4978            } finally {
4979                Binder.restoreCallingIdentity(origId);
4980            }
4981        }
4982    }
4983
4984    @Override
4985    public final void finishHeavyWeightApp() {
4986        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4987                != PackageManager.PERMISSION_GRANTED) {
4988            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4989                    + Binder.getCallingPid()
4990                    + ", uid=" + Binder.getCallingUid()
4991                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4992            Slog.w(TAG, msg);
4993            throw new SecurityException(msg);
4994        }
4995
4996        synchronized(this) {
4997            if (mHeavyWeightProcess == null) {
4998                return;
4999            }
5000
5001            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
5002            for (int i = 0; i < activities.size(); i++) {
5003                ActivityRecord r = activities.get(i);
5004                if (!r.finishing && r.isInStackLocked()) {
5005                    r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
5006                            null, "finish-heavy", true);
5007                }
5008            }
5009
5010            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5011                    mHeavyWeightProcess.userId, 0));
5012            mHeavyWeightProcess = null;
5013        }
5014    }
5015
5016    @Override
5017    public void crashApplication(int uid, int initialPid, String packageName, int userId,
5018            String message) {
5019        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5020                != PackageManager.PERMISSION_GRANTED) {
5021            String msg = "Permission Denial: crashApplication() from pid="
5022                    + Binder.getCallingPid()
5023                    + ", uid=" + Binder.getCallingUid()
5024                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5025            Slog.w(TAG, msg);
5026            throw new SecurityException(msg);
5027        }
5028
5029        synchronized(this) {
5030            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
5031        }
5032    }
5033
5034    @Override
5035    public final void finishSubActivity(IBinder token, String resultWho,
5036            int requestCode) {
5037        synchronized(this) {
5038            final long origId = Binder.clearCallingIdentity();
5039            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5040            if (r != null) {
5041                r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
5042            }
5043            Binder.restoreCallingIdentity(origId);
5044        }
5045    }
5046
5047    @Override
5048    public boolean finishActivityAffinity(IBinder token) {
5049        synchronized(this) {
5050            final long origId = Binder.clearCallingIdentity();
5051            try {
5052                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5053                if (r == null) {
5054                    return false;
5055                }
5056
5057                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
5058                // can finish.
5059                final TaskRecord task = r.task;
5060                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
5061                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
5062                    mStackSupervisor.showLockTaskToast();
5063                    return false;
5064                }
5065                return task.getStack().finishActivityAffinityLocked(r);
5066            } finally {
5067                Binder.restoreCallingIdentity(origId);
5068            }
5069        }
5070    }
5071
5072    @Override
5073    public void finishVoiceTask(IVoiceInteractionSession session) {
5074        synchronized (this) {
5075            final long origId = Binder.clearCallingIdentity();
5076            try {
5077                // TODO: VI Consider treating local voice interactions and voice tasks
5078                // differently here
5079                mStackSupervisor.finishVoiceTask(session);
5080            } finally {
5081                Binder.restoreCallingIdentity(origId);
5082            }
5083        }
5084
5085    }
5086
5087    @Override
5088    public boolean releaseActivityInstance(IBinder token) {
5089        synchronized(this) {
5090            final long origId = Binder.clearCallingIdentity();
5091            try {
5092                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5093                if (r == null) {
5094                    return false;
5095                }
5096                return r.getStack().safelyDestroyActivityLocked(r, "app-req");
5097            } finally {
5098                Binder.restoreCallingIdentity(origId);
5099            }
5100        }
5101    }
5102
5103    @Override
5104    public void releaseSomeActivities(IApplicationThread appInt) {
5105        synchronized(this) {
5106            final long origId = Binder.clearCallingIdentity();
5107            try {
5108                ProcessRecord app = getRecordForAppLocked(appInt);
5109                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5110            } finally {
5111                Binder.restoreCallingIdentity(origId);
5112            }
5113        }
5114    }
5115
5116    @Override
5117    public boolean willActivityBeVisible(IBinder token) {
5118        synchronized(this) {
5119            ActivityStack stack = ActivityRecord.getStackLocked(token);
5120            if (stack != null) {
5121                return stack.willActivityBeVisibleLocked(token);
5122            }
5123            return false;
5124        }
5125    }
5126
5127    @Override
5128    public void overridePendingTransition(IBinder token, String packageName,
5129            int enterAnim, int exitAnim) {
5130        synchronized(this) {
5131            ActivityRecord self = ActivityRecord.isInStackLocked(token);
5132            if (self == null) {
5133                return;
5134            }
5135
5136            final long origId = Binder.clearCallingIdentity();
5137
5138            if (self.state == ActivityState.RESUMED
5139                    || self.state == ActivityState.PAUSING) {
5140                mWindowManager.overridePendingAppTransition(packageName,
5141                        enterAnim, exitAnim, null);
5142            }
5143
5144            Binder.restoreCallingIdentity(origId);
5145        }
5146    }
5147
5148    /**
5149     * Main function for removing an existing process from the activity manager
5150     * as a result of that process going away.  Clears out all connections
5151     * to the process.
5152     */
5153    private final void handleAppDiedLocked(ProcessRecord app,
5154            boolean restarting, boolean allowRestart) {
5155        int pid = app.pid;
5156        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5157                false /*replacingPid*/);
5158        if (!kept && !restarting) {
5159            removeLruProcessLocked(app);
5160            if (pid > 0) {
5161                ProcessList.remove(pid);
5162            }
5163        }
5164
5165        if (mProfileProc == app) {
5166            clearProfilerLocked();
5167        }
5168
5169        // Remove this application's activities from active lists.
5170        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5171
5172        app.activities.clear();
5173
5174        if (app.instr != null) {
5175            Slog.w(TAG, "Crash of app " + app.processName
5176                  + " running instrumentation " + app.instr.mClass);
5177            Bundle info = new Bundle();
5178            info.putString("shortMsg", "Process crashed.");
5179            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5180        }
5181
5182        mWindowManager.deferSurfaceLayout();
5183        try {
5184            if (!restarting && hasVisibleActivities
5185                    && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5186                // If there was nothing to resume, and we are not already restarting this process, but
5187                // there is a visible activity that is hosted by the process...  then make sure all
5188                // visible activities are running, taking care of restarting this process.
5189                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5190            }
5191        } finally {
5192            mWindowManager.continueSurfaceLayout();
5193        }
5194    }
5195
5196    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5197        IBinder threadBinder = thread.asBinder();
5198        // Find the application record.
5199        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5200            ProcessRecord rec = mLruProcesses.get(i);
5201            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5202                return i;
5203            }
5204        }
5205        return -1;
5206    }
5207
5208    final ProcessRecord getRecordForAppLocked(
5209            IApplicationThread thread) {
5210        if (thread == null) {
5211            return null;
5212        }
5213
5214        int appIndex = getLRURecordIndexForAppLocked(thread);
5215        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5216    }
5217
5218    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5219        // If there are no longer any background processes running,
5220        // and the app that died was not running instrumentation,
5221        // then tell everyone we are now low on memory.
5222        boolean haveBg = false;
5223        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5224            ProcessRecord rec = mLruProcesses.get(i);
5225            if (rec.thread != null
5226                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5227                haveBg = true;
5228                break;
5229            }
5230        }
5231
5232        if (!haveBg) {
5233            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5234            if (doReport) {
5235                long now = SystemClock.uptimeMillis();
5236                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5237                    doReport = false;
5238                } else {
5239                    mLastMemUsageReportTime = now;
5240                }
5241            }
5242            final ArrayList<ProcessMemInfo> memInfos
5243                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5244            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5245            long now = SystemClock.uptimeMillis();
5246            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5247                ProcessRecord rec = mLruProcesses.get(i);
5248                if (rec == dyingProc || rec.thread == null) {
5249                    continue;
5250                }
5251                if (doReport) {
5252                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5253                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5254                }
5255                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5256                    // The low memory report is overriding any current
5257                    // state for a GC request.  Make sure to do
5258                    // heavy/important/visible/foreground processes first.
5259                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5260                        rec.lastRequestedGc = 0;
5261                    } else {
5262                        rec.lastRequestedGc = rec.lastLowMemory;
5263                    }
5264                    rec.reportLowMemory = true;
5265                    rec.lastLowMemory = now;
5266                    mProcessesToGc.remove(rec);
5267                    addProcessToGcListLocked(rec);
5268                }
5269            }
5270            if (doReport) {
5271                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5272                mHandler.sendMessage(msg);
5273            }
5274            scheduleAppGcsLocked();
5275        }
5276    }
5277
5278    final void appDiedLocked(ProcessRecord app) {
5279       appDiedLocked(app, app.pid, app.thread, false);
5280    }
5281
5282    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5283            boolean fromBinderDied) {
5284        // First check if this ProcessRecord is actually active for the pid.
5285        synchronized (mPidsSelfLocked) {
5286            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5287            if (curProc != app) {
5288                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5289                return;
5290            }
5291        }
5292
5293        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5294        synchronized (stats) {
5295            stats.noteProcessDiedLocked(app.info.uid, pid);
5296        }
5297
5298        if (!app.killed) {
5299            if (!fromBinderDied) {
5300                Process.killProcessQuiet(pid);
5301            }
5302            killProcessGroup(app.uid, pid);
5303            app.killed = true;
5304        }
5305
5306        // Clean up already done if the process has been re-started.
5307        if (app.pid == pid && app.thread != null &&
5308                app.thread.asBinder() == thread.asBinder()) {
5309            boolean doLowMem = app.instr == null;
5310            boolean doOomAdj = doLowMem;
5311            if (!app.killedByAm) {
5312                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5313                        + ") has died");
5314                mAllowLowerMemLevel = true;
5315            } else {
5316                // Note that we always want to do oom adj to update our state with the
5317                // new number of procs.
5318                mAllowLowerMemLevel = false;
5319                doLowMem = false;
5320            }
5321            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5322            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5323                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5324            handleAppDiedLocked(app, false, true);
5325
5326            if (doOomAdj) {
5327                updateOomAdjLocked();
5328            }
5329            if (doLowMem) {
5330                doLowMemReportIfNeededLocked(app);
5331            }
5332        } else if (app.pid != pid) {
5333            // A new process has already been started.
5334            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5335                    + ") has died and restarted (pid " + app.pid + ").");
5336            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5337        } else if (DEBUG_PROCESSES) {
5338            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5339                    + thread.asBinder());
5340        }
5341    }
5342
5343    /**
5344     * If a stack trace dump file is configured, dump process stack traces.
5345     * @param clearTraces causes the dump file to be erased prior to the new
5346     *    traces being written, if true; when false, the new traces will be
5347     *    appended to any existing file content.
5348     * @param firstPids of dalvik VM processes to dump stack traces for first
5349     * @param lastPids of dalvik VM processes to dump stack traces for last
5350     * @param nativeProcs optional list of native process names to dump stack crawls
5351     * @return file containing stack traces, or null if no dump file is configured
5352     */
5353    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5354            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5355        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5356        if (tracesPath == null || tracesPath.length() == 0) {
5357            return null;
5358        }
5359
5360        File tracesFile = new File(tracesPath);
5361        try {
5362            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5363            tracesFile.createNewFile();
5364            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5365        } catch (IOException e) {
5366            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5367            return null;
5368        }
5369
5370        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5371        return tracesFile;
5372    }
5373
5374    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5375            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5376        // Use a FileObserver to detect when traces finish writing.
5377        // The order of traces is considered important to maintain for legibility.
5378        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5379            @Override
5380            public synchronized void onEvent(int event, String path) { notify(); }
5381        };
5382
5383        try {
5384            observer.startWatching();
5385
5386            // First collect all of the stacks of the most important pids.
5387            if (firstPids != null) {
5388                try {
5389                    int num = firstPids.size();
5390                    for (int i = 0; i < num; i++) {
5391                        synchronized (observer) {
5392                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5393                                    + firstPids.get(i));
5394                            final long sime = SystemClock.elapsedRealtime();
5395                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5396                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5397                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5398                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5399                        }
5400                    }
5401                } catch (InterruptedException e) {
5402                    Slog.wtf(TAG, e);
5403                }
5404            }
5405
5406            // Next collect the stacks of the native pids
5407            if (nativeProcs != null) {
5408                int[] pids = Process.getPidsForCommands(nativeProcs);
5409                if (pids != null) {
5410                    for (int pid : pids) {
5411                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5412                        final long sime = SystemClock.elapsedRealtime();
5413
5414                        Debug.dumpNativeBacktraceToFileTimeout(pid, tracesPath, 10);
5415                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5416                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5417                    }
5418                }
5419            }
5420
5421            // Lastly, measure CPU usage.
5422            if (processCpuTracker != null) {
5423                processCpuTracker.init();
5424                System.gc();
5425                processCpuTracker.update();
5426                try {
5427                    synchronized (processCpuTracker) {
5428                        processCpuTracker.wait(500); // measure over 1/2 second.
5429                    }
5430                } catch (InterruptedException e) {
5431                }
5432                processCpuTracker.update();
5433
5434                // We'll take the stack crawls of just the top apps using CPU.
5435                final int N = processCpuTracker.countWorkingStats();
5436                int numProcs = 0;
5437                for (int i=0; i<N && numProcs<5; i++) {
5438                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5439                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5440                        numProcs++;
5441                        try {
5442                            synchronized (observer) {
5443                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5444                                        + stats.pid);
5445                                final long stime = SystemClock.elapsedRealtime();
5446                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5447                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5448                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5449                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5450                            }
5451                        } catch (InterruptedException e) {
5452                            Slog.wtf(TAG, e);
5453                        }
5454                    } else if (DEBUG_ANR) {
5455                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5456                                + stats.pid);
5457                    }
5458                }
5459            }
5460        } finally {
5461            observer.stopWatching();
5462        }
5463    }
5464
5465    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5466        if (true || IS_USER_BUILD) {
5467            return;
5468        }
5469        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5470        if (tracesPath == null || tracesPath.length() == 0) {
5471            return;
5472        }
5473
5474        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5475        StrictMode.allowThreadDiskWrites();
5476        try {
5477            final File tracesFile = new File(tracesPath);
5478            final File tracesDir = tracesFile.getParentFile();
5479            final File tracesTmp = new File(tracesDir, "__tmp__");
5480            try {
5481                if (tracesFile.exists()) {
5482                    tracesTmp.delete();
5483                    tracesFile.renameTo(tracesTmp);
5484                }
5485                StringBuilder sb = new StringBuilder();
5486                Time tobj = new Time();
5487                tobj.set(System.currentTimeMillis());
5488                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5489                sb.append(": ");
5490                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5491                sb.append(" since ");
5492                sb.append(msg);
5493                FileOutputStream fos = new FileOutputStream(tracesFile);
5494                fos.write(sb.toString().getBytes());
5495                if (app == null) {
5496                    fos.write("\n*** No application process!".getBytes());
5497                }
5498                fos.close();
5499                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5500            } catch (IOException e) {
5501                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5502                return;
5503            }
5504
5505            if (app != null) {
5506                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5507                firstPids.add(app.pid);
5508                dumpStackTraces(tracesPath, firstPids, null, null, null);
5509            }
5510
5511            File lastTracesFile = null;
5512            File curTracesFile = null;
5513            for (int i=9; i>=0; i--) {
5514                String name = String.format(Locale.US, "slow%02d.txt", i);
5515                curTracesFile = new File(tracesDir, name);
5516                if (curTracesFile.exists()) {
5517                    if (lastTracesFile != null) {
5518                        curTracesFile.renameTo(lastTracesFile);
5519                    } else {
5520                        curTracesFile.delete();
5521                    }
5522                }
5523                lastTracesFile = curTracesFile;
5524            }
5525            tracesFile.renameTo(curTracesFile);
5526            if (tracesTmp.exists()) {
5527                tracesTmp.renameTo(tracesFile);
5528            }
5529        } finally {
5530            StrictMode.setThreadPolicy(oldPolicy);
5531        }
5532    }
5533
5534    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5535        if (!mLaunchWarningShown) {
5536            mLaunchWarningShown = true;
5537            mUiHandler.post(new Runnable() {
5538                @Override
5539                public void run() {
5540                    synchronized (ActivityManagerService.this) {
5541                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5542                        d.show();
5543                        mUiHandler.postDelayed(new Runnable() {
5544                            @Override
5545                            public void run() {
5546                                synchronized (ActivityManagerService.this) {
5547                                    d.dismiss();
5548                                    mLaunchWarningShown = false;
5549                                }
5550                            }
5551                        }, 4000);
5552                    }
5553                }
5554            });
5555        }
5556    }
5557
5558    @Override
5559    public boolean clearApplicationUserData(final String packageName,
5560            final IPackageDataObserver observer, int userId) {
5561        enforceNotIsolatedCaller("clearApplicationUserData");
5562        int uid = Binder.getCallingUid();
5563        int pid = Binder.getCallingPid();
5564        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5565                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5566
5567
5568        long callingId = Binder.clearCallingIdentity();
5569        try {
5570            IPackageManager pm = AppGlobals.getPackageManager();
5571            int pkgUid = -1;
5572            synchronized(this) {
5573                if (getPackageManagerInternalLocked().isPackageDataProtected(
5574                        userId, packageName)) {
5575                    throw new SecurityException(
5576                            "Cannot clear data for a protected package: " + packageName);
5577                }
5578
5579                try {
5580                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5581                } catch (RemoteException e) {
5582                }
5583                if (pkgUid == -1) {
5584                    Slog.w(TAG, "Invalid packageName: " + packageName);
5585                    if (observer != null) {
5586                        try {
5587                            observer.onRemoveCompleted(packageName, false);
5588                        } catch (RemoteException e) {
5589                            Slog.i(TAG, "Observer no longer exists.");
5590                        }
5591                    }
5592                    return false;
5593                }
5594                if (uid == pkgUid || checkComponentPermission(
5595                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5596                        pid, uid, -1, true)
5597                        == PackageManager.PERMISSION_GRANTED) {
5598                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5599                } else {
5600                    throw new SecurityException("PID " + pid + " does not have permission "
5601                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5602                                    + " of package " + packageName);
5603                }
5604
5605                // Remove all tasks match the cleared application package and user
5606                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5607                    final TaskRecord tr = mRecentTasks.get(i);
5608                    final String taskPackageName =
5609                            tr.getBaseIntent().getComponent().getPackageName();
5610                    if (tr.userId != userId) continue;
5611                    if (!taskPackageName.equals(packageName)) continue;
5612                    mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5613                }
5614            }
5615
5616            final int pkgUidF = pkgUid;
5617            final int userIdF = userId;
5618            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5619                @Override
5620                public void onRemoveCompleted(String packageName, boolean succeeded)
5621                        throws RemoteException {
5622                    synchronized (ActivityManagerService.this) {
5623                        finishForceStopPackageLocked(packageName, pkgUidF);
5624                    }
5625
5626                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5627                            Uri.fromParts("package", packageName, null));
5628                    intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
5629                    intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5630                    intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5631                    broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5632                            null, null, 0, null, null, null, null, false, false, userIdF);
5633
5634                    if (observer != null) {
5635                        observer.onRemoveCompleted(packageName, succeeded);
5636                    }
5637                }
5638            };
5639
5640            try {
5641                // Clear application user data
5642                pm.clearApplicationUserData(packageName, localObserver, userId);
5643
5644                synchronized(this) {
5645                    // Remove all permissions granted from/to this package
5646                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5647                }
5648
5649                // Reset notification settings.
5650                INotificationManager inm = NotificationManager.getService();
5651                inm.clearData(packageName, pkgUidF, uid == pkgUidF);
5652            } catch (RemoteException e) {
5653            }
5654        } finally {
5655            Binder.restoreCallingIdentity(callingId);
5656        }
5657        return true;
5658    }
5659
5660    @Override
5661    public void killBackgroundProcesses(final String packageName, int userId) {
5662        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5663                != PackageManager.PERMISSION_GRANTED &&
5664                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5665                        != PackageManager.PERMISSION_GRANTED) {
5666            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5667                    + Binder.getCallingPid()
5668                    + ", uid=" + Binder.getCallingUid()
5669                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5670            Slog.w(TAG, msg);
5671            throw new SecurityException(msg);
5672        }
5673
5674        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5675                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5676        long callingId = Binder.clearCallingIdentity();
5677        try {
5678            IPackageManager pm = AppGlobals.getPackageManager();
5679            synchronized(this) {
5680                int appId = -1;
5681                try {
5682                    appId = UserHandle.getAppId(
5683                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5684                } catch (RemoteException e) {
5685                }
5686                if (appId == -1) {
5687                    Slog.w(TAG, "Invalid packageName: " + packageName);
5688                    return;
5689                }
5690                killPackageProcessesLocked(packageName, appId, userId,
5691                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5692            }
5693        } finally {
5694            Binder.restoreCallingIdentity(callingId);
5695        }
5696    }
5697
5698    @Override
5699    public void killAllBackgroundProcesses() {
5700        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5701                != PackageManager.PERMISSION_GRANTED) {
5702            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5703                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5704                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5705            Slog.w(TAG, msg);
5706            throw new SecurityException(msg);
5707        }
5708
5709        final long callingId = Binder.clearCallingIdentity();
5710        try {
5711            synchronized (this) {
5712                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5713                final int NP = mProcessNames.getMap().size();
5714                for (int ip = 0; ip < NP; ip++) {
5715                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5716                    final int NA = apps.size();
5717                    for (int ia = 0; ia < NA; ia++) {
5718                        final ProcessRecord app = apps.valueAt(ia);
5719                        if (app.persistent) {
5720                            // We don't kill persistent processes.
5721                            continue;
5722                        }
5723                        if (app.removed) {
5724                            procs.add(app);
5725                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5726                            app.removed = true;
5727                            procs.add(app);
5728                        }
5729                    }
5730                }
5731
5732                final int N = procs.size();
5733                for (int i = 0; i < N; i++) {
5734                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5735                }
5736
5737                mAllowLowerMemLevel = true;
5738
5739                updateOomAdjLocked();
5740                doLowMemReportIfNeededLocked(null);
5741            }
5742        } finally {
5743            Binder.restoreCallingIdentity(callingId);
5744        }
5745    }
5746
5747    /**
5748     * Kills all background processes, except those matching any of the
5749     * specified properties.
5750     *
5751     * @param minTargetSdk the target SDK version at or above which to preserve
5752     *                     processes, or {@code -1} to ignore the target SDK
5753     * @param maxProcState the process state at or below which to preserve
5754     *                     processes, or {@code -1} to ignore the process state
5755     */
5756    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5757        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5758                != PackageManager.PERMISSION_GRANTED) {
5759            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5760                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5761                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5762            Slog.w(TAG, msg);
5763            throw new SecurityException(msg);
5764        }
5765
5766        final long callingId = Binder.clearCallingIdentity();
5767        try {
5768            synchronized (this) {
5769                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5770                final int NP = mProcessNames.getMap().size();
5771                for (int ip = 0; ip < NP; ip++) {
5772                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5773                    final int NA = apps.size();
5774                    for (int ia = 0; ia < NA; ia++) {
5775                        final ProcessRecord app = apps.valueAt(ia);
5776                        if (app.removed) {
5777                            procs.add(app);
5778                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5779                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5780                            app.removed = true;
5781                            procs.add(app);
5782                        }
5783                    }
5784                }
5785
5786                final int N = procs.size();
5787                for (int i = 0; i < N; i++) {
5788                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5789                }
5790            }
5791        } finally {
5792            Binder.restoreCallingIdentity(callingId);
5793        }
5794    }
5795
5796    @Override
5797    public void forceStopPackage(final String packageName, int userId) {
5798        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5799                != PackageManager.PERMISSION_GRANTED) {
5800            String msg = "Permission Denial: forceStopPackage() from pid="
5801                    + Binder.getCallingPid()
5802                    + ", uid=" + Binder.getCallingUid()
5803                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5804            Slog.w(TAG, msg);
5805            throw new SecurityException(msg);
5806        }
5807        final int callingPid = Binder.getCallingPid();
5808        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5809                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5810        long callingId = Binder.clearCallingIdentity();
5811        try {
5812            IPackageManager pm = AppGlobals.getPackageManager();
5813            synchronized(this) {
5814                int[] users = userId == UserHandle.USER_ALL
5815                        ? mUserController.getUsers() : new int[] { userId };
5816                for (int user : users) {
5817                    int pkgUid = -1;
5818                    try {
5819                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5820                                user);
5821                    } catch (RemoteException e) {
5822                    }
5823                    if (pkgUid == -1) {
5824                        Slog.w(TAG, "Invalid packageName: " + packageName);
5825                        continue;
5826                    }
5827                    try {
5828                        pm.setPackageStoppedState(packageName, true, user);
5829                    } catch (RemoteException e) {
5830                    } catch (IllegalArgumentException e) {
5831                        Slog.w(TAG, "Failed trying to unstop package "
5832                                + packageName + ": " + e);
5833                    }
5834                    if (mUserController.isUserRunningLocked(user, 0)) {
5835                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5836                        finishForceStopPackageLocked(packageName, pkgUid);
5837                    }
5838                }
5839            }
5840        } finally {
5841            Binder.restoreCallingIdentity(callingId);
5842        }
5843    }
5844
5845    @Override
5846    public void addPackageDependency(String packageName) {
5847        synchronized (this) {
5848            int callingPid = Binder.getCallingPid();
5849            if (callingPid == Process.myPid()) {
5850                //  Yeah, um, no.
5851                return;
5852            }
5853            ProcessRecord proc;
5854            synchronized (mPidsSelfLocked) {
5855                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5856            }
5857            if (proc != null) {
5858                if (proc.pkgDeps == null) {
5859                    proc.pkgDeps = new ArraySet<String>(1);
5860                }
5861                proc.pkgDeps.add(packageName);
5862            }
5863        }
5864    }
5865
5866    /*
5867     * The pkg name and app id have to be specified.
5868     */
5869    @Override
5870    public void killApplication(String pkg, int appId, int userId, String reason) {
5871        if (pkg == null) {
5872            return;
5873        }
5874        // Make sure the uid is valid.
5875        if (appId < 0) {
5876            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5877            return;
5878        }
5879        int callerUid = Binder.getCallingUid();
5880        // Only the system server can kill an application
5881        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5882            // Post an aysnc message to kill the application
5883            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5884            msg.arg1 = appId;
5885            msg.arg2 = userId;
5886            Bundle bundle = new Bundle();
5887            bundle.putString("pkg", pkg);
5888            bundle.putString("reason", reason);
5889            msg.obj = bundle;
5890            mHandler.sendMessage(msg);
5891        } else {
5892            throw new SecurityException(callerUid + " cannot kill pkg: " +
5893                    pkg);
5894        }
5895    }
5896
5897    @Override
5898    public void closeSystemDialogs(String reason) {
5899        enforceNotIsolatedCaller("closeSystemDialogs");
5900
5901        final int pid = Binder.getCallingPid();
5902        final int uid = Binder.getCallingUid();
5903        final long origId = Binder.clearCallingIdentity();
5904        try {
5905            synchronized (this) {
5906                // Only allow this from foreground processes, so that background
5907                // applications can't abuse it to prevent system UI from being shown.
5908                if (uid >= Process.FIRST_APPLICATION_UID) {
5909                    ProcessRecord proc;
5910                    synchronized (mPidsSelfLocked) {
5911                        proc = mPidsSelfLocked.get(pid);
5912                    }
5913                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5914                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5915                                + " from background process " + proc);
5916                        return;
5917                    }
5918                }
5919                closeSystemDialogsLocked(reason);
5920            }
5921        } finally {
5922            Binder.restoreCallingIdentity(origId);
5923        }
5924    }
5925
5926    void closeSystemDialogsLocked(String reason) {
5927        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5928        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5929                | Intent.FLAG_RECEIVER_FOREGROUND);
5930        if (reason != null) {
5931            intent.putExtra("reason", reason);
5932        }
5933        mWindowManager.closeSystemDialogs(reason);
5934
5935        mStackSupervisor.closeSystemDialogsLocked();
5936
5937        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5938                AppOpsManager.OP_NONE, null, false, false,
5939                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5940    }
5941
5942    @Override
5943    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5944        enforceNotIsolatedCaller("getProcessMemoryInfo");
5945        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5946        for (int i=pids.length-1; i>=0; i--) {
5947            ProcessRecord proc;
5948            int oomAdj;
5949            synchronized (this) {
5950                synchronized (mPidsSelfLocked) {
5951                    proc = mPidsSelfLocked.get(pids[i]);
5952                    oomAdj = proc != null ? proc.setAdj : 0;
5953                }
5954            }
5955            infos[i] = new Debug.MemoryInfo();
5956            Debug.getMemoryInfo(pids[i], infos[i]);
5957            if (proc != null) {
5958                synchronized (this) {
5959                    if (proc.thread != null && proc.setAdj == oomAdj) {
5960                        // Record this for posterity if the process has been stable.
5961                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5962                                infos[i].getTotalUss(), false, proc.pkgList);
5963                    }
5964                }
5965            }
5966        }
5967        return infos;
5968    }
5969
5970    @Override
5971    public long[] getProcessPss(int[] pids) {
5972        enforceNotIsolatedCaller("getProcessPss");
5973        long[] pss = new long[pids.length];
5974        for (int i=pids.length-1; i>=0; i--) {
5975            ProcessRecord proc;
5976            int oomAdj;
5977            synchronized (this) {
5978                synchronized (mPidsSelfLocked) {
5979                    proc = mPidsSelfLocked.get(pids[i]);
5980                    oomAdj = proc != null ? proc.setAdj : 0;
5981                }
5982            }
5983            long[] tmpUss = new long[1];
5984            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5985            if (proc != null) {
5986                synchronized (this) {
5987                    if (proc.thread != null && proc.setAdj == oomAdj) {
5988                        // Record this for posterity if the process has been stable.
5989                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5990                    }
5991                }
5992            }
5993        }
5994        return pss;
5995    }
5996
5997    @Override
5998    public void killApplicationProcess(String processName, int uid) {
5999        if (processName == null) {
6000            return;
6001        }
6002
6003        int callerUid = Binder.getCallingUid();
6004        // Only the system server can kill an application
6005        if (callerUid == Process.SYSTEM_UID) {
6006            synchronized (this) {
6007                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
6008                if (app != null && app.thread != null) {
6009                    try {
6010                        app.thread.scheduleSuicide();
6011                    } catch (RemoteException e) {
6012                        // If the other end already died, then our work here is done.
6013                    }
6014                } else {
6015                    Slog.w(TAG, "Process/uid not found attempting kill of "
6016                            + processName + " / " + uid);
6017                }
6018            }
6019        } else {
6020            throw new SecurityException(callerUid + " cannot kill app process: " +
6021                    processName);
6022        }
6023    }
6024
6025    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
6026        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
6027                false, true, false, false, UserHandle.getUserId(uid), reason);
6028    }
6029
6030    private void finishForceStopPackageLocked(final String packageName, int uid) {
6031        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
6032                Uri.fromParts("package", packageName, null));
6033        if (!mProcessesReady) {
6034            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6035                    | Intent.FLAG_RECEIVER_FOREGROUND);
6036        }
6037        intent.putExtra(Intent.EXTRA_UID, uid);
6038        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
6039        broadcastIntentLocked(null, null, intent,
6040                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
6041                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
6042    }
6043
6044
6045    private final boolean killPackageProcessesLocked(String packageName, int appId,
6046            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
6047            boolean doit, boolean evenPersistent, String reason) {
6048        ArrayList<ProcessRecord> procs = new ArrayList<>();
6049
6050        // Remove all processes this package may have touched: all with the
6051        // same UID (except for the system or root user), and all whose name
6052        // matches the package name.
6053        final int NP = mProcessNames.getMap().size();
6054        for (int ip=0; ip<NP; ip++) {
6055            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6056            final int NA = apps.size();
6057            for (int ia=0; ia<NA; ia++) {
6058                ProcessRecord app = apps.valueAt(ia);
6059                if (app.persistent && !evenPersistent) {
6060                    // we don't kill persistent processes
6061                    continue;
6062                }
6063                if (app.removed) {
6064                    if (doit) {
6065                        procs.add(app);
6066                    }
6067                    continue;
6068                }
6069
6070                // Skip process if it doesn't meet our oom adj requirement.
6071                if (app.setAdj < minOomAdj) {
6072                    continue;
6073                }
6074
6075                // If no package is specified, we call all processes under the
6076                // give user id.
6077                if (packageName == null) {
6078                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
6079                        continue;
6080                    }
6081                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6082                        continue;
6083                    }
6084                // Package has been specified, we want to hit all processes
6085                // that match it.  We need to qualify this by the processes
6086                // that are running under the specified app and user ID.
6087                } else {
6088                    final boolean isDep = app.pkgDeps != null
6089                            && app.pkgDeps.contains(packageName);
6090                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6091                        continue;
6092                    }
6093                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
6094                        continue;
6095                    }
6096                    if (!app.pkgList.containsKey(packageName) && !isDep) {
6097                        continue;
6098                    }
6099                }
6100
6101                // Process has passed all conditions, kill it!
6102                if (!doit) {
6103                    return true;
6104                }
6105                app.removed = true;
6106                procs.add(app);
6107            }
6108        }
6109
6110        int N = procs.size();
6111        for (int i=0; i<N; i++) {
6112            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6113        }
6114        updateOomAdjLocked();
6115        return N > 0;
6116    }
6117
6118    private void cleanupDisabledPackageComponentsLocked(
6119            String packageName, int userId, boolean killProcess, String[] changedClasses) {
6120
6121        Set<String> disabledClasses = null;
6122        boolean packageDisabled = false;
6123        IPackageManager pm = AppGlobals.getPackageManager();
6124
6125        if (changedClasses == null) {
6126            // Nothing changed...
6127            return;
6128        }
6129
6130        // Determine enable/disable state of the package and its components.
6131        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6132        for (int i = changedClasses.length - 1; i >= 0; i--) {
6133            final String changedClass = changedClasses[i];
6134
6135            if (changedClass.equals(packageName)) {
6136                try {
6137                    // Entire package setting changed
6138                    enabled = pm.getApplicationEnabledSetting(packageName,
6139                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6140                } catch (Exception e) {
6141                    // No such package/component; probably racing with uninstall.  In any
6142                    // event it means we have nothing further to do here.
6143                    return;
6144                }
6145                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6146                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6147                if (packageDisabled) {
6148                    // Entire package is disabled.
6149                    // No need to continue to check component states.
6150                    disabledClasses = null;
6151                    break;
6152                }
6153            } else {
6154                try {
6155                    enabled = pm.getComponentEnabledSetting(
6156                            new ComponentName(packageName, changedClass),
6157                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6158                } catch (Exception e) {
6159                    // As above, probably racing with uninstall.
6160                    return;
6161                }
6162                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6163                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6164                    if (disabledClasses == null) {
6165                        disabledClasses = new ArraySet<>(changedClasses.length);
6166                    }
6167                    disabledClasses.add(changedClass);
6168                }
6169            }
6170        }
6171
6172        if (!packageDisabled && disabledClasses == null) {
6173            // Nothing to do here...
6174            return;
6175        }
6176
6177        // Clean-up disabled activities.
6178        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6179                packageName, disabledClasses, true, false, userId) && mBooted) {
6180            mStackSupervisor.resumeFocusedStackTopActivityLocked();
6181            mStackSupervisor.scheduleIdleLocked();
6182        }
6183
6184        // Clean-up disabled tasks
6185        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6186
6187        // Clean-up disabled services.
6188        mServices.bringDownDisabledPackageServicesLocked(
6189                packageName, disabledClasses, userId, false, killProcess, true);
6190
6191        // Clean-up disabled providers.
6192        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6193        mProviderMap.collectPackageProvidersLocked(
6194                packageName, disabledClasses, true, false, userId, providers);
6195        for (int i = providers.size() - 1; i >= 0; i--) {
6196            removeDyingProviderLocked(null, providers.get(i), true);
6197        }
6198
6199        // Clean-up disabled broadcast receivers.
6200        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6201            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6202                    packageName, disabledClasses, userId, true);
6203        }
6204
6205    }
6206
6207    final boolean clearBroadcastQueueForUserLocked(int userId) {
6208        boolean didSomething = false;
6209        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6210            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6211                    null, null, userId, true);
6212        }
6213        return didSomething;
6214    }
6215
6216    final boolean forceStopPackageLocked(String packageName, int appId,
6217            boolean callerWillRestart, boolean purgeCache, boolean doit,
6218            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6219        int i;
6220
6221        if (userId == UserHandle.USER_ALL && packageName == null) {
6222            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6223        }
6224
6225        if (appId < 0 && packageName != null) {
6226            try {
6227                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6228                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6229            } catch (RemoteException e) {
6230            }
6231        }
6232
6233        if (doit) {
6234            if (packageName != null) {
6235                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6236                        + " user=" + userId + ": " + reason);
6237            } else {
6238                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6239            }
6240
6241            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6242        }
6243
6244        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6245                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6246                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6247
6248        didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName);
6249
6250        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6251                packageName, null, doit, evenPersistent, userId)) {
6252            if (!doit) {
6253                return true;
6254            }
6255            didSomething = true;
6256        }
6257
6258        if (mServices.bringDownDisabledPackageServicesLocked(
6259                packageName, null, userId, evenPersistent, true, doit)) {
6260            if (!doit) {
6261                return true;
6262            }
6263            didSomething = true;
6264        }
6265
6266        if (packageName == null) {
6267            // Remove all sticky broadcasts from this user.
6268            mStickyBroadcasts.remove(userId);
6269        }
6270
6271        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6272        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6273                userId, providers)) {
6274            if (!doit) {
6275                return true;
6276            }
6277            didSomething = true;
6278        }
6279        for (i = providers.size() - 1; i >= 0; i--) {
6280            removeDyingProviderLocked(null, providers.get(i), true);
6281        }
6282
6283        // Remove transient permissions granted from/to this package/user
6284        removeUriPermissionsForPackageLocked(packageName, userId, false);
6285
6286        if (doit) {
6287            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6288                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6289                        packageName, null, userId, doit);
6290            }
6291        }
6292
6293        if (packageName == null || uninstalling) {
6294            // Remove pending intents.  For now we only do this when force
6295            // stopping users, because we have some problems when doing this
6296            // for packages -- app widgets are not currently cleaned up for
6297            // such packages, so they can be left with bad pending intents.
6298            if (mIntentSenderRecords.size() > 0) {
6299                Iterator<WeakReference<PendingIntentRecord>> it
6300                        = mIntentSenderRecords.values().iterator();
6301                while (it.hasNext()) {
6302                    WeakReference<PendingIntentRecord> wpir = it.next();
6303                    if (wpir == null) {
6304                        it.remove();
6305                        continue;
6306                    }
6307                    PendingIntentRecord pir = wpir.get();
6308                    if (pir == null) {
6309                        it.remove();
6310                        continue;
6311                    }
6312                    if (packageName == null) {
6313                        // Stopping user, remove all objects for the user.
6314                        if (pir.key.userId != userId) {
6315                            // Not the same user, skip it.
6316                            continue;
6317                        }
6318                    } else {
6319                        if (UserHandle.getAppId(pir.uid) != appId) {
6320                            // Different app id, skip it.
6321                            continue;
6322                        }
6323                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6324                            // Different user, skip it.
6325                            continue;
6326                        }
6327                        if (!pir.key.packageName.equals(packageName)) {
6328                            // Different package, skip it.
6329                            continue;
6330                        }
6331                    }
6332                    if (!doit) {
6333                        return true;
6334                    }
6335                    didSomething = true;
6336                    it.remove();
6337                    pir.canceled = true;
6338                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6339                        pir.key.activity.pendingResults.remove(pir.ref);
6340                    }
6341                }
6342            }
6343        }
6344
6345        if (doit) {
6346            if (purgeCache && packageName != null) {
6347                AttributeCache ac = AttributeCache.instance();
6348                if (ac != null) {
6349                    ac.removePackage(packageName);
6350                }
6351            }
6352            if (mBooted) {
6353                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6354                mStackSupervisor.scheduleIdleLocked();
6355            }
6356        }
6357
6358        return didSomething;
6359    }
6360
6361    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6362        return removeProcessNameLocked(name, uid, null);
6363    }
6364
6365    private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
6366            final ProcessRecord expecting) {
6367        ProcessRecord old = mProcessNames.get(name, uid);
6368        // Only actually remove when the currently recorded value matches the
6369        // record that we expected; if it doesn't match then we raced with a
6370        // newly created process and we don't want to destroy the new one.
6371        if ((expecting == null) || (old == expecting)) {
6372            mProcessNames.remove(name, uid);
6373        }
6374        if (old != null && old.uidRecord != null) {
6375            old.uidRecord.numProcs--;
6376            if (old.uidRecord.numProcs == 0) {
6377                // No more processes using this uid, tell clients it is gone.
6378                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6379                        "No more processes in " + old.uidRecord);
6380                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6381                mActiveUids.remove(uid);
6382                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6383            }
6384            old.uidRecord = null;
6385        }
6386        mIsolatedProcesses.remove(uid);
6387        return old;
6388    }
6389
6390    private final void addProcessNameLocked(ProcessRecord proc) {
6391        // We shouldn't already have a process under this name, but just in case we
6392        // need to clean up whatever may be there now.
6393        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6394        if (old == proc && proc.persistent) {
6395            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6396            Slog.w(TAG, "Re-adding persistent process " + proc);
6397        } else if (old != null) {
6398            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6399        }
6400        UidRecord uidRec = mActiveUids.get(proc.uid);
6401        if (uidRec == null) {
6402            uidRec = new UidRecord(proc.uid);
6403            // This is the first appearance of the uid, report it now!
6404            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6405                    "Creating new process uid: " + uidRec);
6406            if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0) {
6407                uidRec.setWhitelist = uidRec.curWhitelist = true;
6408            }
6409            mActiveUids.put(proc.uid, uidRec);
6410            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6411            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6412        }
6413        proc.uidRecord = uidRec;
6414
6415        // Reset render thread tid if it was already set, so new process can set it again.
6416        proc.renderThreadTid = 0;
6417        uidRec.numProcs++;
6418        mProcessNames.put(proc.processName, proc.uid, proc);
6419        if (proc.isolated) {
6420            mIsolatedProcesses.put(proc.uid, proc);
6421        }
6422    }
6423
6424    boolean removeProcessLocked(ProcessRecord app,
6425            boolean callerWillRestart, boolean allowRestart, String reason) {
6426        final String name = app.processName;
6427        final int uid = app.uid;
6428        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6429            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6430
6431        ProcessRecord old = mProcessNames.get(name, uid);
6432        if (old != app) {
6433            // This process is no longer active, so nothing to do.
6434            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6435            return false;
6436        }
6437        removeProcessNameLocked(name, uid);
6438        if (mHeavyWeightProcess == app) {
6439            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6440                    mHeavyWeightProcess.userId, 0));
6441            mHeavyWeightProcess = null;
6442        }
6443        boolean needRestart = false;
6444        if (app.pid > 0 && app.pid != MY_PID) {
6445            int pid = app.pid;
6446            synchronized (mPidsSelfLocked) {
6447                mPidsSelfLocked.remove(pid);
6448                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6449            }
6450            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6451            if (app.isolated) {
6452                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6453            }
6454            boolean willRestart = false;
6455            if (app.persistent && !app.isolated) {
6456                if (!callerWillRestart) {
6457                    willRestart = true;
6458                } else {
6459                    needRestart = true;
6460                }
6461            }
6462            app.kill(reason, true);
6463            handleAppDiedLocked(app, willRestart, allowRestart);
6464            if (willRestart) {
6465                removeLruProcessLocked(app);
6466                addAppLocked(app.info, null, false, null /* ABI override */);
6467            }
6468        } else {
6469            mRemovedProcesses.add(app);
6470        }
6471
6472        return needRestart;
6473    }
6474
6475    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6476        cleanupAppInLaunchingProvidersLocked(app, true);
6477        removeProcessLocked(app, false, true, "timeout publishing content providers");
6478    }
6479
6480    private final void processStartTimedOutLocked(ProcessRecord app) {
6481        final int pid = app.pid;
6482        boolean gone = false;
6483        synchronized (mPidsSelfLocked) {
6484            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6485            if (knownApp != null && knownApp.thread == null) {
6486                mPidsSelfLocked.remove(pid);
6487                gone = true;
6488            }
6489        }
6490
6491        if (gone) {
6492            Slog.w(TAG, "Process " + app + " failed to attach");
6493            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6494                    pid, app.uid, app.processName);
6495            removeProcessNameLocked(app.processName, app.uid);
6496            if (mHeavyWeightProcess == app) {
6497                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6498                        mHeavyWeightProcess.userId, 0));
6499                mHeavyWeightProcess = null;
6500            }
6501            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6502            if (app.isolated) {
6503                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6504            }
6505            // Take care of any launching providers waiting for this process.
6506            cleanupAppInLaunchingProvidersLocked(app, true);
6507            // Take care of any services that are waiting for the process.
6508            mServices.processStartTimedOutLocked(app);
6509            app.kill("start timeout", true);
6510            removeLruProcessLocked(app);
6511            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6512                Slog.w(TAG, "Unattached app died before backup, skipping");
6513                mHandler.post(new Runnable() {
6514                @Override
6515                    public void run(){
6516                        try {
6517                            IBackupManager bm = IBackupManager.Stub.asInterface(
6518                                    ServiceManager.getService(Context.BACKUP_SERVICE));
6519                            bm.agentDisconnected(app.info.packageName);
6520                        } catch (RemoteException e) {
6521                            // Can't happen; the backup manager is local
6522                        }
6523                    }
6524                });
6525            }
6526            if (isPendingBroadcastProcessLocked(pid)) {
6527                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6528                skipPendingBroadcastLocked(pid);
6529            }
6530        } else {
6531            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6532        }
6533    }
6534
6535    private final boolean attachApplicationLocked(IApplicationThread thread,
6536            int pid) {
6537
6538        // Find the application record that is being attached...  either via
6539        // the pid if we are running in multiple processes, or just pull the
6540        // next app record if we are emulating process with anonymous threads.
6541        ProcessRecord app;
6542        long startTime = SystemClock.uptimeMillis();
6543        if (pid != MY_PID && pid >= 0) {
6544            synchronized (mPidsSelfLocked) {
6545                app = mPidsSelfLocked.get(pid);
6546            }
6547        } else {
6548            app = null;
6549        }
6550
6551        if (app == null) {
6552            Slog.w(TAG, "No pending application record for pid " + pid
6553                    + " (IApplicationThread " + thread + "); dropping process");
6554            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6555            if (pid > 0 && pid != MY_PID) {
6556                Process.killProcessQuiet(pid);
6557                //TODO: killProcessGroup(app.info.uid, pid);
6558            } else {
6559                try {
6560                    thread.scheduleExit();
6561                } catch (Exception e) {
6562                    // Ignore exceptions.
6563                }
6564            }
6565            return false;
6566        }
6567
6568        // If this application record is still attached to a previous
6569        // process, clean it up now.
6570        if (app.thread != null) {
6571            handleAppDiedLocked(app, true, true);
6572        }
6573
6574        // Tell the process all about itself.
6575
6576        if (DEBUG_ALL) Slog.v(
6577                TAG, "Binding process pid " + pid + " to record " + app);
6578
6579        final String processName = app.processName;
6580        try {
6581            AppDeathRecipient adr = new AppDeathRecipient(
6582                    app, pid, thread);
6583            thread.asBinder().linkToDeath(adr, 0);
6584            app.deathRecipient = adr;
6585        } catch (RemoteException e) {
6586            app.resetPackageList(mProcessStats);
6587            startProcessLocked(app, "link fail", processName);
6588            return false;
6589        }
6590
6591        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6592
6593        app.makeActive(thread, mProcessStats);
6594        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6595        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6596        app.forcingToForeground = null;
6597        updateProcessForegroundLocked(app, false, false);
6598        app.hasShownUi = false;
6599        app.debugging = false;
6600        app.cached = false;
6601        app.killedByAm = false;
6602        app.killed = false;
6603
6604
6605        // We carefully use the same state that PackageManager uses for
6606        // filtering, since we use this flag to decide if we need to install
6607        // providers when user is unlocked later
6608        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6609
6610        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6611
6612        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6613        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6614
6615        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6616            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6617            msg.obj = app;
6618            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6619        }
6620
6621        checkTime(startTime, "attachApplicationLocked: before bindApplication");
6622
6623        if (!normalMode) {
6624            Slog.i(TAG, "Launching preboot mode app: " + app);
6625        }
6626
6627        if (DEBUG_ALL) Slog.v(
6628            TAG, "New app record " + app
6629            + " thread=" + thread.asBinder() + " pid=" + pid);
6630        try {
6631            int testMode = ApplicationThreadConstants.DEBUG_OFF;
6632            if (mDebugApp != null && mDebugApp.equals(processName)) {
6633                testMode = mWaitForDebugger
6634                    ? ApplicationThreadConstants.DEBUG_WAIT
6635                    : ApplicationThreadConstants.DEBUG_ON;
6636                app.debugging = true;
6637                if (mDebugTransient) {
6638                    mDebugApp = mOrigDebugApp;
6639                    mWaitForDebugger = mOrigWaitForDebugger;
6640                }
6641            }
6642            String profileFile = app.instr != null ? app.instr.mProfileFile : null;
6643            ParcelFileDescriptor profileFd = null;
6644            int samplingInterval = 0;
6645            boolean profileAutoStop = false;
6646            boolean profileStreamingOutput = false;
6647            if (mProfileApp != null && mProfileApp.equals(processName)) {
6648                mProfileProc = app;
6649                profileFile = mProfileFile;
6650                profileFd = mProfileFd;
6651                samplingInterval = mSamplingInterval;
6652                profileAutoStop = mAutoStopProfiler;
6653                profileStreamingOutput = mStreamingOutput;
6654            }
6655            boolean enableTrackAllocation = false;
6656            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6657                enableTrackAllocation = true;
6658                mTrackAllocationApp = null;
6659            }
6660
6661            // If the app is being launched for restore or full backup, set it up specially
6662            boolean isRestrictedBackupMode = false;
6663            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6664                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6665                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6666                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6667                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6668            }
6669
6670            if (app.instr != null) {
6671                notifyPackageUse(app.instr.mClass.getPackageName(),
6672                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6673            }
6674            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6675                    + processName + " with config " + getGlobalConfiguration());
6676            ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
6677            app.compat = compatibilityInfoForPackageLocked(appInfo);
6678            if (profileFd != null) {
6679                profileFd = profileFd.dup();
6680            }
6681            ProfilerInfo profilerInfo = profileFile == null ? null
6682                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop,
6683                                       profileStreamingOutput);
6684
6685            // We deprecated Build.SERIAL and only apps that target pre NMR1
6686            // SDK can see it. Since access to the serial is now behind a
6687            // permission we push down the value.
6688            String buildSerial = Build.UNKNOWN;
6689            // TODO: SHTOPSHIP Uncomment the check when clients migrate
6690//            if (appInfo.targetSdkVersion <= Build.VERSION_CODES.N_MR1) {
6691                buildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
6692                        ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
6693                        .getSerial();
6694//            }
6695
6696            // Check if this is a secondary process that should be incorporated into some
6697            // currently active instrumentation.  (Note we do this AFTER all of the profiling
6698            // stuff above because profiling can currently happen only in the primary
6699            // instrumentation process.)
6700            if (mActiveInstrumentation.size() > 0 && app.instr == null) {
6701                for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
6702                    ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
6703                    if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
6704                        if (aInstr.mTargetProcesses.length == 0) {
6705                            // This is the wildcard mode, where every process brought up for
6706                            // the target instrumentation should be included.
6707                            if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
6708                                app.instr = aInstr;
6709                                aInstr.mRunningProcesses.add(app);
6710                            }
6711                        } else {
6712                            for (String proc : aInstr.mTargetProcesses) {
6713                                if (proc.equals(app.processName)) {
6714                                    app.instr = aInstr;
6715                                    aInstr.mRunningProcesses.add(app);
6716                                    break;
6717                                }
6718                            }
6719                        }
6720                    }
6721                }
6722            }
6723
6724            checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
6725            if (app.instr != null) {
6726                thread.bindApplication(processName, appInfo, providers,
6727                        app.instr.mClass,
6728                        profilerInfo, app.instr.mArguments,
6729                        app.instr.mWatcher,
6730                        app.instr.mUiAutomationConnection, testMode,
6731                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
6732                        isRestrictedBackupMode || !normalMode, app.persistent,
6733                        new Configuration(getGlobalConfiguration()), app.compat,
6734                        getCommonServicesLocked(app.isolated),
6735                        mCoreSettingsObserver.getCoreSettingsLocked(),
6736                        buildSerial);
6737            } else {
6738                thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
6739                        null, null, null, testMode,
6740                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
6741                        isRestrictedBackupMode || !normalMode, app.persistent,
6742                        new Configuration(getGlobalConfiguration()), app.compat,
6743                        getCommonServicesLocked(app.isolated),
6744                        mCoreSettingsObserver.getCoreSettingsLocked(),
6745                        buildSerial);
6746            }
6747
6748            checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
6749            updateLruProcessLocked(app, false, null);
6750            checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
6751            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6752        } catch (Exception e) {
6753            // todo: Yikes!  What should we do?  For now we will try to
6754            // start another process, but that could easily get us in
6755            // an infinite loop of restarting processes...
6756            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6757
6758            app.resetPackageList(mProcessStats);
6759            app.unlinkDeathRecipient();
6760            startProcessLocked(app, "bind fail", processName);
6761            return false;
6762        }
6763
6764        // Remove this record from the list of starting applications.
6765        mPersistentStartingProcesses.remove(app);
6766        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6767                "Attach application locked removing on hold: " + app);
6768        mProcessesOnHold.remove(app);
6769
6770        boolean badApp = false;
6771        boolean didSomething = false;
6772
6773        // See if the top visible activity is waiting to run in this process...
6774        if (normalMode) {
6775            try {
6776                if (mStackSupervisor.attachApplicationLocked(app)) {
6777                    didSomething = true;
6778                }
6779            } catch (Exception e) {
6780                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6781                badApp = true;
6782            }
6783        }
6784
6785        // Find any services that should be running in this process...
6786        if (!badApp) {
6787            try {
6788                didSomething |= mServices.attachApplicationLocked(app, processName);
6789                checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
6790            } catch (Exception e) {
6791                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6792                badApp = true;
6793            }
6794        }
6795
6796        // Check if a next-broadcast receiver is in this process...
6797        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6798            try {
6799                didSomething |= sendPendingBroadcastsLocked(app);
6800                checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
6801            } catch (Exception e) {
6802                // If the app died trying to launch the receiver we declare it 'bad'
6803                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6804                badApp = true;
6805            }
6806        }
6807
6808        // Check whether the next backup agent is in this process...
6809        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6810            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6811                    "New app is backup target, launching agent for " + app);
6812            notifyPackageUse(mBackupTarget.appInfo.packageName,
6813                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6814            try {
6815                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6816                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6817                        mBackupTarget.backupMode);
6818            } catch (Exception e) {
6819                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6820                badApp = true;
6821            }
6822        }
6823
6824        if (badApp) {
6825            app.kill("error during init", true);
6826            handleAppDiedLocked(app, false, true);
6827            return false;
6828        }
6829
6830        if (!didSomething) {
6831            updateOomAdjLocked();
6832            checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
6833        }
6834
6835        return true;
6836    }
6837
6838    @Override
6839    public final void attachApplication(IApplicationThread thread) {
6840        synchronized (this) {
6841            int callingPid = Binder.getCallingPid();
6842            final long origId = Binder.clearCallingIdentity();
6843            attachApplicationLocked(thread, callingPid);
6844            Binder.restoreCallingIdentity(origId);
6845        }
6846    }
6847
6848    @Override
6849    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6850        final long origId = Binder.clearCallingIdentity();
6851        synchronized (this) {
6852            ActivityStack stack = ActivityRecord.getStackLocked(token);
6853            if (stack != null) {
6854                ActivityRecord r =
6855                        mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
6856                                false /* processPausingActivities */, config);
6857                if (stopProfiling) {
6858                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6859                        try {
6860                            mProfileFd.close();
6861                        } catch (IOException e) {
6862                        }
6863                        clearProfilerLocked();
6864                    }
6865                }
6866            }
6867        }
6868        Binder.restoreCallingIdentity(origId);
6869    }
6870
6871    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6872        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6873                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6874    }
6875
6876    void enableScreenAfterBoot() {
6877        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6878                SystemClock.uptimeMillis());
6879        mWindowManager.enableScreenAfterBoot();
6880
6881        synchronized (this) {
6882            updateEventDispatchingLocked();
6883        }
6884    }
6885
6886    @Override
6887    public void showBootMessage(final CharSequence msg, final boolean always) {
6888        if (Binder.getCallingUid() != Process.myUid()) {
6889            throw new SecurityException();
6890        }
6891        mWindowManager.showBootMessage(msg, always);
6892    }
6893
6894    @Override
6895    public void keyguardGoingAway(int flags) {
6896        enforceNotIsolatedCaller("keyguardGoingAway");
6897        final long token = Binder.clearCallingIdentity();
6898        try {
6899            synchronized (this) {
6900                mKeyguardController.keyguardGoingAway(flags);
6901            }
6902        } finally {
6903            Binder.restoreCallingIdentity(token);
6904        }
6905    }
6906
6907    /**
6908     * @return whther the keyguard is currently locked.
6909     */
6910    boolean isKeyguardLocked() {
6911        return mKeyguardController.isKeyguardLocked();
6912    }
6913
6914    final void finishBooting() {
6915        synchronized (this) {
6916            if (!mBootAnimationComplete) {
6917                mCallFinishBooting = true;
6918                return;
6919            }
6920            mCallFinishBooting = false;
6921        }
6922
6923        ArraySet<String> completedIsas = new ArraySet<String>();
6924        for (String abi : Build.SUPPORTED_ABIS) {
6925            Process.zygoteProcess.establishZygoteConnectionForAbi(abi);
6926            final String instructionSet = VMRuntime.getInstructionSet(abi);
6927            if (!completedIsas.contains(instructionSet)) {
6928                try {
6929                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6930                } catch (InstallerException e) {
6931                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6932                            e.getMessage() +")");
6933                }
6934                completedIsas.add(instructionSet);
6935            }
6936        }
6937
6938        IntentFilter pkgFilter = new IntentFilter();
6939        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6940        pkgFilter.addDataScheme("package");
6941        mContext.registerReceiver(new BroadcastReceiver() {
6942            @Override
6943            public void onReceive(Context context, Intent intent) {
6944                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6945                if (pkgs != null) {
6946                    for (String pkg : pkgs) {
6947                        synchronized (ActivityManagerService.this) {
6948                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6949                                    0, "query restart")) {
6950                                setResultCode(Activity.RESULT_OK);
6951                                return;
6952                            }
6953                        }
6954                    }
6955                }
6956            }
6957        }, pkgFilter);
6958
6959        IntentFilter dumpheapFilter = new IntentFilter();
6960        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6961        mContext.registerReceiver(new BroadcastReceiver() {
6962            @Override
6963            public void onReceive(Context context, Intent intent) {
6964                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6965                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6966                } else {
6967                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6968                }
6969            }
6970        }, dumpheapFilter);
6971
6972        // Let system services know.
6973        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6974
6975        synchronized (this) {
6976            // Ensure that any processes we had put on hold are now started
6977            // up.
6978            final int NP = mProcessesOnHold.size();
6979            if (NP > 0) {
6980                ArrayList<ProcessRecord> procs =
6981                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6982                for (int ip=0; ip<NP; ip++) {
6983                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6984                            + procs.get(ip));
6985                    startProcessLocked(procs.get(ip), "on-hold", null);
6986                }
6987            }
6988
6989            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6990                // Start looking for apps that are abusing wake locks.
6991                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6992                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6993                // Tell anyone interested that we are done booting!
6994                SystemProperties.set("sys.boot_completed", "1");
6995
6996                // And trigger dev.bootcomplete if we are not showing encryption progress
6997                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6998                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6999                    SystemProperties.set("dev.bootcomplete", "1");
7000                }
7001                mUserController.sendBootCompletedLocked(
7002                        new IIntentReceiver.Stub() {
7003                            @Override
7004                            public void performReceive(Intent intent, int resultCode,
7005                                    String data, Bundle extras, boolean ordered,
7006                                    boolean sticky, int sendingUser) {
7007                                synchronized (ActivityManagerService.this) {
7008                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
7009                                            true, false);
7010                                }
7011                            }
7012                        });
7013                scheduleStartProfilesLocked();
7014            }
7015        }
7016    }
7017
7018    @Override
7019    public void bootAnimationComplete() {
7020        final boolean callFinishBooting;
7021        synchronized (this) {
7022            callFinishBooting = mCallFinishBooting;
7023            mBootAnimationComplete = true;
7024        }
7025        if (callFinishBooting) {
7026            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7027            finishBooting();
7028            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7029        }
7030    }
7031
7032    final void ensureBootCompleted() {
7033        boolean booting;
7034        boolean enableScreen;
7035        synchronized (this) {
7036            booting = mBooting;
7037            mBooting = false;
7038            enableScreen = !mBooted;
7039            mBooted = true;
7040        }
7041
7042        if (booting) {
7043            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7044            finishBooting();
7045            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7046        }
7047
7048        if (enableScreen) {
7049            enableScreenAfterBoot();
7050        }
7051    }
7052
7053    @Override
7054    public final void activityResumed(IBinder token) {
7055        final long origId = Binder.clearCallingIdentity();
7056        synchronized(this) {
7057            ActivityRecord.activityResumedLocked(token);
7058            mWindowManager.notifyAppResumedFinished(token);
7059        }
7060        Binder.restoreCallingIdentity(origId);
7061    }
7062
7063    @Override
7064    public final void activityPaused(IBinder token) {
7065        final long origId = Binder.clearCallingIdentity();
7066        synchronized(this) {
7067            ActivityStack stack = ActivityRecord.getStackLocked(token);
7068            if (stack != null) {
7069                stack.activityPausedLocked(token, false);
7070            }
7071        }
7072        Binder.restoreCallingIdentity(origId);
7073    }
7074
7075    @Override
7076    public final void activityStopped(IBinder token, Bundle icicle,
7077            PersistableBundle persistentState, CharSequence description) {
7078        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
7079
7080        // Refuse possible leaked file descriptors
7081        if (icicle != null && icicle.hasFileDescriptors()) {
7082            throw new IllegalArgumentException("File descriptors passed in Bundle");
7083        }
7084
7085        final long origId = Binder.clearCallingIdentity();
7086
7087        synchronized (this) {
7088            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7089            if (r != null) {
7090                r.activityStoppedLocked(icicle, persistentState, description);
7091            }
7092        }
7093
7094        trimApplications();
7095
7096        Binder.restoreCallingIdentity(origId);
7097    }
7098
7099    @Override
7100    public final void activityDestroyed(IBinder token) {
7101        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
7102        synchronized (this) {
7103            ActivityStack stack = ActivityRecord.getStackLocked(token);
7104            if (stack != null) {
7105                stack.activityDestroyedLocked(token, "activityDestroyed");
7106            }
7107        }
7108    }
7109
7110    @Override
7111    public final void activityRelaunched(IBinder token) {
7112        final long origId = Binder.clearCallingIdentity();
7113        synchronized (this) {
7114            mStackSupervisor.activityRelaunchedLocked(token);
7115        }
7116        Binder.restoreCallingIdentity(origId);
7117    }
7118
7119    @Override
7120    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
7121            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
7122        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
7123                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
7124        synchronized (this) {
7125            ActivityRecord record = ActivityRecord.isInStackLocked(token);
7126            if (record == null) {
7127                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
7128                        + "found for: " + token);
7129            }
7130            record.setSizeConfigurations(horizontalSizeConfiguration,
7131                    verticalSizeConfigurations, smallestSizeConfigurations);
7132        }
7133    }
7134
7135    @Override
7136    public final void backgroundResourcesReleased(IBinder token) {
7137        final long origId = Binder.clearCallingIdentity();
7138        try {
7139            synchronized (this) {
7140                ActivityStack stack = ActivityRecord.getStackLocked(token);
7141                if (stack != null) {
7142                    stack.backgroundResourcesReleased();
7143                }
7144            }
7145        } finally {
7146            Binder.restoreCallingIdentity(origId);
7147        }
7148    }
7149
7150    @Override
7151    public final void notifyLaunchTaskBehindComplete(IBinder token) {
7152        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7153    }
7154
7155    @Override
7156    public final void notifyEnterAnimationComplete(IBinder token) {
7157        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7158    }
7159
7160    @Override
7161    public String getCallingPackage(IBinder token) {
7162        synchronized (this) {
7163            ActivityRecord r = getCallingRecordLocked(token);
7164            return r != null ? r.info.packageName : null;
7165        }
7166    }
7167
7168    @Override
7169    public ComponentName getCallingActivity(IBinder token) {
7170        synchronized (this) {
7171            ActivityRecord r = getCallingRecordLocked(token);
7172            return r != null ? r.intent.getComponent() : null;
7173        }
7174    }
7175
7176    private ActivityRecord getCallingRecordLocked(IBinder token) {
7177        ActivityRecord r = ActivityRecord.isInStackLocked(token);
7178        if (r == null) {
7179            return null;
7180        }
7181        return r.resultTo;
7182    }
7183
7184    @Override
7185    public ComponentName getActivityClassForToken(IBinder token) {
7186        synchronized(this) {
7187            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7188            if (r == null) {
7189                return null;
7190            }
7191            return r.intent.getComponent();
7192        }
7193    }
7194
7195    @Override
7196    public String getPackageForToken(IBinder token) {
7197        synchronized(this) {
7198            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7199            if (r == null) {
7200                return null;
7201            }
7202            return r.packageName;
7203        }
7204    }
7205
7206    @Override
7207    public boolean isRootVoiceInteraction(IBinder token) {
7208        synchronized(this) {
7209            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7210            if (r == null) {
7211                return false;
7212            }
7213            return r.rootVoiceInteraction;
7214        }
7215    }
7216
7217    @Override
7218    public IIntentSender getIntentSender(int type,
7219            String packageName, IBinder token, String resultWho,
7220            int requestCode, Intent[] intents, String[] resolvedTypes,
7221            int flags, Bundle bOptions, int userId) {
7222        enforceNotIsolatedCaller("getIntentSender");
7223        // Refuse possible leaked file descriptors
7224        if (intents != null) {
7225            if (intents.length < 1) {
7226                throw new IllegalArgumentException("Intents array length must be >= 1");
7227            }
7228            for (int i=0; i<intents.length; i++) {
7229                Intent intent = intents[i];
7230                if (intent != null) {
7231                    if (intent.hasFileDescriptors()) {
7232                        throw new IllegalArgumentException("File descriptors passed in Intent");
7233                    }
7234                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7235                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7236                        throw new IllegalArgumentException(
7237                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7238                    }
7239                    intents[i] = new Intent(intent);
7240                }
7241            }
7242            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7243                throw new IllegalArgumentException(
7244                        "Intent array length does not match resolvedTypes length");
7245            }
7246        }
7247        if (bOptions != null) {
7248            if (bOptions.hasFileDescriptors()) {
7249                throw new IllegalArgumentException("File descriptors passed in options");
7250            }
7251        }
7252
7253        synchronized(this) {
7254            int callingUid = Binder.getCallingUid();
7255            int origUserId = userId;
7256            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7257                    type == ActivityManager.INTENT_SENDER_BROADCAST,
7258                    ALLOW_NON_FULL, "getIntentSender", null);
7259            if (origUserId == UserHandle.USER_CURRENT) {
7260                // We don't want to evaluate this until the pending intent is
7261                // actually executed.  However, we do want to always do the
7262                // security checking for it above.
7263                userId = UserHandle.USER_CURRENT;
7264            }
7265            try {
7266                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7267                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7268                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7269                    if (!UserHandle.isSameApp(callingUid, uid)) {
7270                        String msg = "Permission Denial: getIntentSender() from pid="
7271                            + Binder.getCallingPid()
7272                            + ", uid=" + Binder.getCallingUid()
7273                            + ", (need uid=" + uid + ")"
7274                            + " is not allowed to send as package " + packageName;
7275                        Slog.w(TAG, msg);
7276                        throw new SecurityException(msg);
7277                    }
7278                }
7279
7280                return getIntentSenderLocked(type, packageName, callingUid, userId,
7281                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7282
7283            } catch (RemoteException e) {
7284                throw new SecurityException(e);
7285            }
7286        }
7287    }
7288
7289    IIntentSender getIntentSenderLocked(int type, String packageName,
7290            int callingUid, int userId, IBinder token, String resultWho,
7291            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7292            Bundle bOptions) {
7293        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7294        ActivityRecord activity = null;
7295        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7296            activity = ActivityRecord.isInStackLocked(token);
7297            if (activity == null) {
7298                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7299                return null;
7300            }
7301            if (activity.finishing) {
7302                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7303                return null;
7304            }
7305        }
7306
7307        // We're going to be splicing together extras before sending, so we're
7308        // okay poking into any contained extras.
7309        if (intents != null) {
7310            for (int i = 0; i < intents.length; i++) {
7311                intents[i].setDefusable(true);
7312            }
7313        }
7314        Bundle.setDefusable(bOptions, true);
7315
7316        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7317        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7318        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7319        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7320                |PendingIntent.FLAG_UPDATE_CURRENT);
7321
7322        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7323                type, packageName, activity, resultWho,
7324                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7325        WeakReference<PendingIntentRecord> ref;
7326        ref = mIntentSenderRecords.get(key);
7327        PendingIntentRecord rec = ref != null ? ref.get() : null;
7328        if (rec != null) {
7329            if (!cancelCurrent) {
7330                if (updateCurrent) {
7331                    if (rec.key.requestIntent != null) {
7332                        rec.key.requestIntent.replaceExtras(intents != null ?
7333                                intents[intents.length - 1] : null);
7334                    }
7335                    if (intents != null) {
7336                        intents[intents.length-1] = rec.key.requestIntent;
7337                        rec.key.allIntents = intents;
7338                        rec.key.allResolvedTypes = resolvedTypes;
7339                    } else {
7340                        rec.key.allIntents = null;
7341                        rec.key.allResolvedTypes = null;
7342                    }
7343                }
7344                return rec;
7345            }
7346            rec.canceled = true;
7347            mIntentSenderRecords.remove(key);
7348        }
7349        if (noCreate) {
7350            return rec;
7351        }
7352        rec = new PendingIntentRecord(this, key, callingUid);
7353        mIntentSenderRecords.put(key, rec.ref);
7354        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7355            if (activity.pendingResults == null) {
7356                activity.pendingResults
7357                        = new HashSet<WeakReference<PendingIntentRecord>>();
7358            }
7359            activity.pendingResults.add(rec.ref);
7360        }
7361        return rec;
7362    }
7363
7364    @Override
7365    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7366            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7367        if (target instanceof PendingIntentRecord) {
7368            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7369                    finishedReceiver, requiredPermission, options);
7370        } else {
7371            if (intent == null) {
7372                // Weird case: someone has given us their own custom IIntentSender, and now
7373                // they have someone else trying to send to it but of course this isn't
7374                // really a PendingIntent, so there is no base Intent, and the caller isn't
7375                // supplying an Intent... but we never want to dispatch a null Intent to
7376                // a receiver, so um...  let's make something up.
7377                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7378                intent = new Intent(Intent.ACTION_MAIN);
7379            }
7380            try {
7381                target.send(code, intent, resolvedType, null, requiredPermission, options);
7382            } catch (RemoteException e) {
7383            }
7384            // Platform code can rely on getting a result back when the send is done, but if
7385            // this intent sender is from outside of the system we can't rely on it doing that.
7386            // So instead we don't give it the result receiver, and instead just directly
7387            // report the finish immediately.
7388            if (finishedReceiver != null) {
7389                try {
7390                    finishedReceiver.performReceive(intent, 0,
7391                            null, null, false, false, UserHandle.getCallingUserId());
7392                } catch (RemoteException e) {
7393                }
7394            }
7395            return 0;
7396        }
7397    }
7398
7399    /**
7400     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7401     */
7402    void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7403        if (DEBUG_WHITELISTS) {
7404            Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7405                    + targetUid + ", " + duration + ")");
7406        }
7407
7408        if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid)
7409                != PackageManager.PERMISSION_GRANTED) {
7410            synchronized (mPidsSelfLocked) {
7411                final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7412                if (pr == null) {
7413                    Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid "
7414                            + callerPid);
7415                    return;
7416                }
7417                if (!pr.whitelistManager) {
7418                    if (DEBUG_WHITELISTS) {
7419                        Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid
7420                                + ": pid " + callerPid + " is not allowed");
7421                    }
7422                    return;
7423                }
7424            }
7425        }
7426
7427        final long token = Binder.clearCallingIdentity();
7428        try {
7429            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7430                    true, "pe from uid:" + callerUid);
7431        } finally {
7432            Binder.restoreCallingIdentity(token);
7433        }
7434    }
7435
7436    @Override
7437    public void cancelIntentSender(IIntentSender sender) {
7438        if (!(sender instanceof PendingIntentRecord)) {
7439            return;
7440        }
7441        synchronized(this) {
7442            PendingIntentRecord rec = (PendingIntentRecord)sender;
7443            try {
7444                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7445                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7446                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7447                    String msg = "Permission Denial: cancelIntentSender() from pid="
7448                        + Binder.getCallingPid()
7449                        + ", uid=" + Binder.getCallingUid()
7450                        + " is not allowed to cancel packges "
7451                        + rec.key.packageName;
7452                    Slog.w(TAG, msg);
7453                    throw new SecurityException(msg);
7454                }
7455            } catch (RemoteException e) {
7456                throw new SecurityException(e);
7457            }
7458            cancelIntentSenderLocked(rec, true);
7459        }
7460    }
7461
7462    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7463        rec.canceled = true;
7464        mIntentSenderRecords.remove(rec.key);
7465        if (cleanActivity && rec.key.activity != null) {
7466            rec.key.activity.pendingResults.remove(rec.ref);
7467        }
7468    }
7469
7470    @Override
7471    public String getPackageForIntentSender(IIntentSender pendingResult) {
7472        if (!(pendingResult instanceof PendingIntentRecord)) {
7473            return null;
7474        }
7475        try {
7476            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7477            return res.key.packageName;
7478        } catch (ClassCastException e) {
7479        }
7480        return null;
7481    }
7482
7483    @Override
7484    public int getUidForIntentSender(IIntentSender sender) {
7485        if (sender instanceof PendingIntentRecord) {
7486            try {
7487                PendingIntentRecord res = (PendingIntentRecord)sender;
7488                return res.uid;
7489            } catch (ClassCastException e) {
7490            }
7491        }
7492        return -1;
7493    }
7494
7495    @Override
7496    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7497        if (!(pendingResult instanceof PendingIntentRecord)) {
7498            return false;
7499        }
7500        try {
7501            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7502            if (res.key.allIntents == null) {
7503                return false;
7504            }
7505            for (int i=0; i<res.key.allIntents.length; i++) {
7506                Intent intent = res.key.allIntents[i];
7507                if (intent.getPackage() != null && intent.getComponent() != null) {
7508                    return false;
7509                }
7510            }
7511            return true;
7512        } catch (ClassCastException e) {
7513        }
7514        return false;
7515    }
7516
7517    @Override
7518    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7519        if (!(pendingResult instanceof PendingIntentRecord)) {
7520            return false;
7521        }
7522        try {
7523            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7524            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7525                return true;
7526            }
7527            return false;
7528        } catch (ClassCastException e) {
7529        }
7530        return false;
7531    }
7532
7533    @Override
7534    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7535        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7536                "getIntentForIntentSender()");
7537        if (!(pendingResult instanceof PendingIntentRecord)) {
7538            return null;
7539        }
7540        try {
7541            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7542            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7543        } catch (ClassCastException e) {
7544        }
7545        return null;
7546    }
7547
7548    @Override
7549    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7550        if (!(pendingResult instanceof PendingIntentRecord)) {
7551            return null;
7552        }
7553        try {
7554            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7555            synchronized (this) {
7556                return getTagForIntentSenderLocked(res, prefix);
7557            }
7558        } catch (ClassCastException e) {
7559        }
7560        return null;
7561    }
7562
7563    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7564        final Intent intent = res.key.requestIntent;
7565        if (intent != null) {
7566            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7567                    || res.lastTagPrefix.equals(prefix))) {
7568                return res.lastTag;
7569            }
7570            res.lastTagPrefix = prefix;
7571            final StringBuilder sb = new StringBuilder(128);
7572            if (prefix != null) {
7573                sb.append(prefix);
7574            }
7575            if (intent.getAction() != null) {
7576                sb.append(intent.getAction());
7577            } else if (intent.getComponent() != null) {
7578                intent.getComponent().appendShortString(sb);
7579            } else {
7580                sb.append("?");
7581            }
7582            return res.lastTag = sb.toString();
7583        }
7584        return null;
7585    }
7586
7587    @Override
7588    public void setProcessLimit(int max) {
7589        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7590                "setProcessLimit()");
7591        synchronized (this) {
7592            mConstants.setOverrideMaxCachedProcesses(max);
7593        }
7594        trimApplications();
7595    }
7596
7597    @Override
7598    public int getProcessLimit() {
7599        synchronized (this) {
7600            return mConstants.getOverrideMaxCachedProcesses();
7601        }
7602    }
7603
7604    void foregroundTokenDied(ForegroundToken token) {
7605        synchronized (ActivityManagerService.this) {
7606            synchronized (mPidsSelfLocked) {
7607                ForegroundToken cur
7608                    = mForegroundProcesses.get(token.pid);
7609                if (cur != token) {
7610                    return;
7611                }
7612                mForegroundProcesses.remove(token.pid);
7613                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7614                if (pr == null) {
7615                    return;
7616                }
7617                pr.forcingToForeground = null;
7618                updateProcessForegroundLocked(pr, false, false);
7619            }
7620            updateOomAdjLocked();
7621        }
7622    }
7623
7624    @Override
7625    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7626        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7627                "setProcessForeground()");
7628        synchronized(this) {
7629            boolean changed = false;
7630
7631            synchronized (mPidsSelfLocked) {
7632                ProcessRecord pr = mPidsSelfLocked.get(pid);
7633                if (pr == null && isForeground) {
7634                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7635                    return;
7636                }
7637                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7638                if (oldToken != null) {
7639                    oldToken.token.unlinkToDeath(oldToken, 0);
7640                    mForegroundProcesses.remove(pid);
7641                    if (pr != null) {
7642                        pr.forcingToForeground = null;
7643                    }
7644                    changed = true;
7645                }
7646                if (isForeground && token != null) {
7647                    ForegroundToken newToken = new ForegroundToken() {
7648                        @Override
7649                        public void binderDied() {
7650                            foregroundTokenDied(this);
7651                        }
7652                    };
7653                    newToken.pid = pid;
7654                    newToken.token = token;
7655                    try {
7656                        token.linkToDeath(newToken, 0);
7657                        mForegroundProcesses.put(pid, newToken);
7658                        pr.forcingToForeground = token;
7659                        changed = true;
7660                    } catch (RemoteException e) {
7661                        // If the process died while doing this, we will later
7662                        // do the cleanup with the process death link.
7663                    }
7664                }
7665            }
7666
7667            if (changed) {
7668                updateOomAdjLocked();
7669            }
7670        }
7671    }
7672
7673    @Override
7674    public boolean isAppForeground(int uid) throws RemoteException {
7675        synchronized (this) {
7676            UidRecord uidRec = mActiveUids.get(uid);
7677            if (uidRec == null || uidRec.idle) {
7678                return false;
7679            }
7680            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7681        }
7682    }
7683
7684    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7685    // be guarded by permission checking.
7686    int getUidState(int uid) {
7687        synchronized (this) {
7688            UidRecord uidRec = mActiveUids.get(uid);
7689            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7690        }
7691    }
7692
7693    @Override
7694    public boolean isInMultiWindowMode(IBinder token) {
7695        final long origId = Binder.clearCallingIdentity();
7696        try {
7697            synchronized(this) {
7698                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7699                if (r == null) {
7700                    return false;
7701                }
7702                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7703                return !r.task.mFullscreen;
7704            }
7705        } finally {
7706            Binder.restoreCallingIdentity(origId);
7707        }
7708    }
7709
7710    @Override
7711    public boolean isInPictureInPictureMode(IBinder token) {
7712        final long origId = Binder.clearCallingIdentity();
7713        try {
7714            synchronized(this) {
7715                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7716                if (stack == null) {
7717                    return false;
7718                }
7719                return stack.mStackId == PINNED_STACK_ID;
7720            }
7721        } finally {
7722            Binder.restoreCallingIdentity(origId);
7723        }
7724    }
7725
7726    @Override
7727    public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureArgs args) {
7728        final long origId = Binder.clearCallingIdentity();
7729        try {
7730            synchronized(this) {
7731                final ActivityRecord r = ensureValidPictureInPictureActivityArgsLocked(
7732                        "enterPictureInPictureMode", token, args);
7733
7734                // Activity supports picture-in-picture, now check that we can enter PiP at this
7735                // point, if it is
7736                if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
7737                        false /* noThrow */)) {
7738                    return false;
7739                }
7740
7741                final Runnable enterPipRunnable = () -> {
7742                    // Only update the saved args from the args that are set
7743                    r.pictureInPictureArgs.copyOnlySet(args);
7744                    final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
7745                    final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
7746                    final Rect bounds = mWindowManager.getPictureInPictureBounds(DEFAULT_DISPLAY,
7747                            aspectRatio);
7748                    mStackSupervisor.moveActivityToPinnedStackLocked(r, "enterPictureInPictureMode",
7749                            bounds, true /* moveHomeStackToFront */);
7750                    final PinnedActivityStack stack = mStackSupervisor.getStack(PINNED_STACK_ID);
7751                    stack.setPictureInPictureAspectRatio(aspectRatio);
7752                    stack.setPictureInPictureActions(actions);
7753
7754                    MetricsLogger.action(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_ENTERED,
7755                            r.supportsPictureInPictureWhilePausing);
7756                    logPictureInPictureArgs(args);
7757                };
7758
7759                if (isKeyguardLocked()) {
7760                    // If the keyguard is showing or occluded, then try and dismiss it before
7761                    // entering picture-in-picture (this will prompt the user to authenticate if the
7762                    // device is currently locked).
7763                    try {
7764                        dismissKeyguard(token, new IKeyguardDismissCallback.Stub() {
7765                            @Override
7766                            public void onDismissError() throws RemoteException {
7767                                // Do nothing
7768                            }
7769
7770                            @Override
7771                            public void onDismissSucceeded() throws RemoteException {
7772                                mHandler.post(enterPipRunnable);
7773                            }
7774
7775                            @Override
7776                            public void onDismissCancelled() throws RemoteException {
7777                                // Do nothing
7778                            }
7779                        });
7780                    } catch (RemoteException e) {
7781                        // Local call
7782                    }
7783                } else {
7784                    // Enter picture in picture immediately otherwise
7785                    enterPipRunnable.run();
7786                }
7787                return true;
7788            }
7789        } finally {
7790            Binder.restoreCallingIdentity(origId);
7791        }
7792    }
7793
7794    @Override
7795    public void setPictureInPictureArgs(IBinder token, final PictureInPictureArgs args) {
7796        final long origId = Binder.clearCallingIdentity();
7797        try {
7798            synchronized(this) {
7799                final ActivityRecord r = ensureValidPictureInPictureActivityArgsLocked(
7800                        "setPictureInPictureArgs", token, args);
7801
7802                // Only update the saved args from the args that are set
7803                r.pictureInPictureArgs.copyOnlySet(args);
7804                if (r.getStack().getStackId() == PINNED_STACK_ID) {
7805                    // If the activity is already in picture-in-picture, update the pinned stack now
7806                    final PinnedActivityStack stack = r.getStack();
7807                    stack.setPictureInPictureAspectRatio(r.pictureInPictureArgs.getAspectRatio());
7808                    stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
7809                }
7810                logPictureInPictureArgs(args);
7811            }
7812        } finally {
7813            Binder.restoreCallingIdentity(origId);
7814        }
7815    }
7816
7817    private void logPictureInPictureArgs(PictureInPictureArgs args) {
7818        if (args.hasSetActions()) {
7819            MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
7820                    args.getActions().size());
7821        }
7822        if (args.hasSetAspectRatio()) {
7823            LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
7824            lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, args.getAspectRatio());
7825            MetricsLogger.action(lm);
7826        }
7827    }
7828
7829    /**
7830     * Checks the state of the system and the activity associated with the given {@param token} to
7831     * verify that picture-in-picture is supported for that activity.
7832     *
7833     * @return the activity record for the given {@param token} if all the checks pass.
7834     */
7835    private ActivityRecord ensureValidPictureInPictureActivityArgsLocked(String caller,
7836            IBinder token, PictureInPictureArgs args) {
7837        if (!mSupportsPictureInPicture) {
7838            throw new IllegalStateException(caller
7839                    + ": Device doesn't support picture-in-picture mode.");
7840        }
7841
7842        final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7843        if (r == null) {
7844            throw new IllegalStateException(caller
7845                    + ": Can't find activity for token=" + token);
7846        }
7847
7848        if (!r.supportsPictureInPicture()) {
7849            throw new IllegalStateException(caller
7850                    + ": Current activity does not support picture-in-picture.");
7851        }
7852
7853        if (!StackId.isAllowedToEnterPictureInPicture(r.getStack().getStackId())) {
7854            throw new IllegalStateException(caller
7855                    + ": Activities on the home, assistant, or recents stack not supported");
7856        }
7857
7858        if (args.hasSetAspectRatio()
7859                && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
7860                        args.getAspectRatio())) {
7861            final float minAspectRatio = mContext.getResources().getFloat(
7862                    com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
7863            final float maxAspectRatio = mContext.getResources().getFloat(
7864                    com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
7865            throw new IllegalArgumentException(String.format(caller
7866                    + ": Aspect ratio is too extreme (must be between %f and %f).",
7867                            minAspectRatio, maxAspectRatio));
7868        }
7869
7870        if (args.hasSetActions()
7871                && args.getActions().size() > ActivityManager.getMaxNumPictureInPictureActions()) {
7872            throw new IllegalArgumentException(String.format(caller + ": Invalid number of"
7873                    + "picture-in-picture actions.  Only a maximum of %d actions allowed",
7874                            ActivityManager.getMaxNumPictureInPictureActions()));
7875        }
7876
7877        return r;
7878    }
7879
7880    // =========================================================
7881    // PROCESS INFO
7882    // =========================================================
7883
7884    static class ProcessInfoService extends IProcessInfoService.Stub {
7885        final ActivityManagerService mActivityManagerService;
7886        ProcessInfoService(ActivityManagerService activityManagerService) {
7887            mActivityManagerService = activityManagerService;
7888        }
7889
7890        @Override
7891        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7892            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7893                    /*in*/ pids, /*out*/ states, null);
7894        }
7895
7896        @Override
7897        public void getProcessStatesAndOomScoresFromPids(
7898                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7899            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7900                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7901        }
7902    }
7903
7904    /**
7905     * For each PID in the given input array, write the current process state
7906     * for that process into the states array, or -1 to indicate that no
7907     * process with the given PID exists. If scores array is provided, write
7908     * the oom score for the process into the scores array, with INVALID_ADJ
7909     * indicating the PID doesn't exist.
7910     */
7911    public void getProcessStatesAndOomScoresForPIDs(
7912            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7913        if (scores != null) {
7914            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7915                    "getProcessStatesAndOomScoresForPIDs()");
7916        }
7917
7918        if (pids == null) {
7919            throw new NullPointerException("pids");
7920        } else if (states == null) {
7921            throw new NullPointerException("states");
7922        } else if (pids.length != states.length) {
7923            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7924        } else if (scores != null && pids.length != scores.length) {
7925            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7926        }
7927
7928        synchronized (mPidsSelfLocked) {
7929            for (int i = 0; i < pids.length; i++) {
7930                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7931                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7932                        pr.curProcState;
7933                if (scores != null) {
7934                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7935                }
7936            }
7937        }
7938    }
7939
7940    // =========================================================
7941    // PERMISSIONS
7942    // =========================================================
7943
7944    static class PermissionController extends IPermissionController.Stub {
7945        ActivityManagerService mActivityManagerService;
7946        PermissionController(ActivityManagerService activityManagerService) {
7947            mActivityManagerService = activityManagerService;
7948        }
7949
7950        @Override
7951        public boolean checkPermission(String permission, int pid, int uid) {
7952            return mActivityManagerService.checkPermission(permission, pid,
7953                    uid) == PackageManager.PERMISSION_GRANTED;
7954        }
7955
7956        @Override
7957        public String[] getPackagesForUid(int uid) {
7958            return mActivityManagerService.mContext.getPackageManager()
7959                    .getPackagesForUid(uid);
7960        }
7961
7962        @Override
7963        public boolean isRuntimePermission(String permission) {
7964            try {
7965                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7966                        .getPermissionInfo(permission, 0);
7967                return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
7968                        == PermissionInfo.PROTECTION_DANGEROUS;
7969            } catch (NameNotFoundException nnfe) {
7970                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7971            }
7972            return false;
7973        }
7974    }
7975
7976    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7977        @Override
7978        public int checkComponentPermission(String permission, int pid, int uid,
7979                int owningUid, boolean exported) {
7980            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7981                    owningUid, exported);
7982        }
7983
7984        @Override
7985        public Object getAMSLock() {
7986            return ActivityManagerService.this;
7987        }
7988    }
7989
7990    /**
7991     * This can be called with or without the global lock held.
7992     */
7993    int checkComponentPermission(String permission, int pid, int uid,
7994            int owningUid, boolean exported) {
7995        if (pid == MY_PID) {
7996            return PackageManager.PERMISSION_GRANTED;
7997        }
7998        return ActivityManager.checkComponentPermission(permission, uid,
7999                owningUid, exported);
8000    }
8001
8002    /**
8003     * As the only public entry point for permissions checking, this method
8004     * can enforce the semantic that requesting a check on a null global
8005     * permission is automatically denied.  (Internally a null permission
8006     * string is used when calling {@link #checkComponentPermission} in cases
8007     * when only uid-based security is needed.)
8008     *
8009     * This can be called with or without the global lock held.
8010     */
8011    @Override
8012    public int checkPermission(String permission, int pid, int uid) {
8013        if (permission == null) {
8014            return PackageManager.PERMISSION_DENIED;
8015        }
8016        return checkComponentPermission(permission, pid, uid, -1, true);
8017    }
8018
8019    @Override
8020    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
8021        if (permission == null) {
8022            return PackageManager.PERMISSION_DENIED;
8023        }
8024
8025        // We might be performing an operation on behalf of an indirect binder
8026        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
8027        // client identity accordingly before proceeding.
8028        Identity tlsIdentity = sCallerIdentity.get();
8029        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8030            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
8031                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
8032            uid = tlsIdentity.uid;
8033            pid = tlsIdentity.pid;
8034        }
8035
8036        return checkComponentPermission(permission, pid, uid, -1, true);
8037    }
8038
8039    /**
8040     * Binder IPC calls go through the public entry point.
8041     * This can be called with or without the global lock held.
8042     */
8043    int checkCallingPermission(String permission) {
8044        return checkPermission(permission,
8045                Binder.getCallingPid(),
8046                UserHandle.getAppId(Binder.getCallingUid()));
8047    }
8048
8049    /**
8050     * This can be called with or without the global lock held.
8051     */
8052    void enforceCallingPermission(String permission, String func) {
8053        if (checkCallingPermission(permission)
8054                == PackageManager.PERMISSION_GRANTED) {
8055            return;
8056        }
8057
8058        String msg = "Permission Denial: " + func + " from pid="
8059                + Binder.getCallingPid()
8060                + ", uid=" + Binder.getCallingUid()
8061                + " requires " + permission;
8062        Slog.w(TAG, msg);
8063        throw new SecurityException(msg);
8064    }
8065
8066    /**
8067     * Determine if UID is holding permissions required to access {@link Uri} in
8068     * the given {@link ProviderInfo}. Final permission checking is always done
8069     * in {@link ContentProvider}.
8070     */
8071    private final boolean checkHoldingPermissionsLocked(
8072            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
8073        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8074                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
8075        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
8076            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
8077                    != PERMISSION_GRANTED) {
8078                return false;
8079            }
8080        }
8081        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
8082    }
8083
8084    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
8085            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
8086        if (pi.applicationInfo.uid == uid) {
8087            return true;
8088        } else if (!pi.exported) {
8089            return false;
8090        }
8091
8092        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
8093        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
8094        try {
8095            // check if target holds top-level <provider> permissions
8096            if (!readMet && pi.readPermission != null && considerUidPermissions
8097                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
8098                readMet = true;
8099            }
8100            if (!writeMet && pi.writePermission != null && considerUidPermissions
8101                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
8102                writeMet = true;
8103            }
8104
8105            // track if unprotected read/write is allowed; any denied
8106            // <path-permission> below removes this ability
8107            boolean allowDefaultRead = pi.readPermission == null;
8108            boolean allowDefaultWrite = pi.writePermission == null;
8109
8110            // check if target holds any <path-permission> that match uri
8111            final PathPermission[] pps = pi.pathPermissions;
8112            if (pps != null) {
8113                final String path = grantUri.uri.getPath();
8114                int i = pps.length;
8115                while (i > 0 && (!readMet || !writeMet)) {
8116                    i--;
8117                    PathPermission pp = pps[i];
8118                    if (pp.match(path)) {
8119                        if (!readMet) {
8120                            final String pprperm = pp.getReadPermission();
8121                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8122                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
8123                                    + ": match=" + pp.match(path)
8124                                    + " check=" + pm.checkUidPermission(pprperm, uid));
8125                            if (pprperm != null) {
8126                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
8127                                        == PERMISSION_GRANTED) {
8128                                    readMet = true;
8129                                } else {
8130                                    allowDefaultRead = false;
8131                                }
8132                            }
8133                        }
8134                        if (!writeMet) {
8135                            final String ppwperm = pp.getWritePermission();
8136                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8137                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
8138                                    + ": match=" + pp.match(path)
8139                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
8140                            if (ppwperm != null) {
8141                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
8142                                        == PERMISSION_GRANTED) {
8143                                    writeMet = true;
8144                                } else {
8145                                    allowDefaultWrite = false;
8146                                }
8147                            }
8148                        }
8149                    }
8150                }
8151            }
8152
8153            // grant unprotected <provider> read/write, if not blocked by
8154            // <path-permission> above
8155            if (allowDefaultRead) readMet = true;
8156            if (allowDefaultWrite) writeMet = true;
8157
8158        } catch (RemoteException e) {
8159            return false;
8160        }
8161
8162        return readMet && writeMet;
8163    }
8164
8165    public boolean isAppStartModeDisabled(int uid, String packageName) {
8166        synchronized (this) {
8167            return getAppStartModeLocked(uid, packageName, 0, -1, false, true)
8168                    == ActivityManager.APP_START_MODE_DISABLED;
8169        }
8170    }
8171
8172    // Unified app-op and target sdk check
8173    int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8174        // Apps that target O+ are always subject to background check
8175        if (mConstants.ENFORCE_BG_CHECK && packageTargetSdk >= Build.VERSION_CODES.O) {
8176            if (DEBUG_BACKGROUND_CHECK) {
8177                Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted");
8178            }
8179            return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8180        }
8181        // ...and legacy apps get an AppOp check
8182        int appop = mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND,
8183                uid, packageName);
8184        if (DEBUG_BACKGROUND_CHECK) {
8185            Slog.i(TAG, "Legacy app " + uid + "/" + packageName + " bg appop " + appop);
8186        }
8187        switch (appop) {
8188            case AppOpsManager.MODE_ALLOWED:
8189                return ActivityManager.APP_START_MODE_NORMAL;
8190            case AppOpsManager.MODE_IGNORED:
8191                return ActivityManager.APP_START_MODE_DELAYED;
8192            default:
8193                return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8194        }
8195    }
8196
8197    // Service launch is available to apps with run-in-background exemptions but
8198    // some other background operations are not.  If we're doing a check
8199    // of service-launch policy, allow those callers to proceed unrestricted.
8200    int appServicesRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8201        // Persistent app?
8202        if (mPackageManagerInt.isPackagePersistent(packageName)) {
8203            if (DEBUG_BACKGROUND_CHECK) {
8204                Slog.i(TAG, "App " + uid + "/" + packageName
8205                        + " is persistent; not restricted in background");
8206            }
8207            return ActivityManager.APP_START_MODE_NORMAL;
8208        }
8209
8210        // Non-persistent but background whitelisted?
8211        if (uidOnBackgroundWhitelist(uid)) {
8212            if (DEBUG_BACKGROUND_CHECK) {
8213                Slog.i(TAG, "App " + uid + "/" + packageName
8214                        + " on background whitelist; not restricted in background");
8215            }
8216            return ActivityManager.APP_START_MODE_NORMAL;
8217        }
8218
8219        // Is this app on the battery whitelist?
8220        if (isOnDeviceIdleWhitelistLocked(uid)) {
8221            if (DEBUG_BACKGROUND_CHECK) {
8222                Slog.i(TAG, "App " + uid + "/" + packageName
8223                        + " on idle whitelist; not restricted in background");
8224            }
8225            return ActivityManager.APP_START_MODE_NORMAL;
8226        }
8227
8228        // None of the service-policy criteria apply, so we apply the common criteria
8229        return appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk);
8230    }
8231
8232    int getAppStartModeLocked(int uid, String packageName, int packageTargetSdk,
8233            int callingPid, boolean alwaysRestrict, boolean disabledOnly) {
8234        UidRecord uidRec = mActiveUids.get(uid);
8235        if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid + " pkg="
8236                + packageName + " rec=" + uidRec + " always=" + alwaysRestrict + " idle="
8237                + (uidRec != null ? uidRec.idle : false));
8238        if (uidRec == null || alwaysRestrict || uidRec.idle) {
8239            boolean ephemeral;
8240            if (uidRec == null) {
8241                ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
8242                        UserHandle.getUserId(uid), packageName);
8243            } else {
8244                ephemeral = uidRec.ephemeral;
8245            }
8246
8247            if (ephemeral) {
8248                // We are hard-core about ephemeral apps not running in the background.
8249                return ActivityManager.APP_START_MODE_DISABLED;
8250            } else {
8251                if (disabledOnly) {
8252                    // The caller is only interested in whether app starts are completely
8253                    // disabled for the given package (that is, it is an instant app).  So
8254                    // we don't need to go further, which is all just seeing if we should
8255                    // apply a "delayed" mode for a regular app.
8256                    return ActivityManager.APP_START_MODE_NORMAL;
8257                }
8258                final int startMode = (alwaysRestrict)
8259                        ? appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk)
8260                        : appServicesRestrictedInBackgroundLocked(uid, packageName,
8261                                packageTargetSdk);
8262                if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid
8263                        + " pkg=" + packageName + " startMode=" + startMode
8264                        + " onwhitelist=" + isOnDeviceIdleWhitelistLocked(uid));
8265                if (startMode == ActivityManager.APP_START_MODE_DELAYED) {
8266                    // This is an old app that has been forced into a "compatible as possible"
8267                    // mode of background check.  To increase compatibility, we will allow other
8268                    // foreground apps to cause its services to start.
8269                    if (callingPid >= 0) {
8270                        ProcessRecord proc;
8271                        synchronized (mPidsSelfLocked) {
8272                            proc = mPidsSelfLocked.get(callingPid);
8273                        }
8274                        if (proc != null && proc.curProcState
8275                                < ActivityManager.PROCESS_STATE_RECEIVER) {
8276                            // Whoever is instigating this is in the foreground, so we will allow it
8277                            // to go through.
8278                            return ActivityManager.APP_START_MODE_NORMAL;
8279                        }
8280                    }
8281                }
8282                return startMode;
8283            }
8284        }
8285        return ActivityManager.APP_START_MODE_NORMAL;
8286    }
8287
8288    boolean isOnDeviceIdleWhitelistLocked(int uid) {
8289        final int appId = UserHandle.getAppId(uid);
8290        return Arrays.binarySearch(mDeviceIdleWhitelist, appId) >= 0
8291                || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0;
8292    }
8293
8294    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
8295        ProviderInfo pi = null;
8296        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
8297        if (cpr != null) {
8298            pi = cpr.info;
8299        } else {
8300            try {
8301                pi = AppGlobals.getPackageManager().resolveContentProvider(
8302                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
8303                        userHandle);
8304            } catch (RemoteException ex) {
8305            }
8306        }
8307        return pi;
8308    }
8309
8310    void grantEphemeralAccessLocked(int userId, Intent intent,
8311            int targetAppId, int ephemeralAppId) {
8312        getPackageManagerInternalLocked().
8313                grantEphemeralAccess(userId, intent, targetAppId, ephemeralAppId);
8314    }
8315
8316    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
8317        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8318        if (targetUris != null) {
8319            return targetUris.get(grantUri);
8320        }
8321        return null;
8322    }
8323
8324    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
8325            String targetPkg, int targetUid, GrantUri grantUri) {
8326        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8327        if (targetUris == null) {
8328            targetUris = Maps.newArrayMap();
8329            mGrantedUriPermissions.put(targetUid, targetUris);
8330        }
8331
8332        UriPermission perm = targetUris.get(grantUri);
8333        if (perm == null) {
8334            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
8335            targetUris.put(grantUri, perm);
8336        }
8337
8338        return perm;
8339    }
8340
8341    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
8342            final int modeFlags) {
8343        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
8344        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
8345                : UriPermission.STRENGTH_OWNED;
8346
8347        // Root gets to do everything.
8348        if (uid == 0) {
8349            return true;
8350        }
8351
8352        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8353        if (perms == null) return false;
8354
8355        // First look for exact match
8356        final UriPermission exactPerm = perms.get(grantUri);
8357        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
8358            return true;
8359        }
8360
8361        // No exact match, look for prefixes
8362        final int N = perms.size();
8363        for (int i = 0; i < N; i++) {
8364            final UriPermission perm = perms.valueAt(i);
8365            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
8366                    && perm.getStrength(modeFlags) >= minStrength) {
8367                return true;
8368            }
8369        }
8370
8371        return false;
8372    }
8373
8374    /**
8375     * @param uri This uri must NOT contain an embedded userId.
8376     * @param userId The userId in which the uri is to be resolved.
8377     */
8378    @Override
8379    public int checkUriPermission(Uri uri, int pid, int uid,
8380            final int modeFlags, int userId, IBinder callerToken) {
8381        enforceNotIsolatedCaller("checkUriPermission");
8382
8383        // Another redirected-binder-call permissions check as in
8384        // {@link checkPermissionWithToken}.
8385        Identity tlsIdentity = sCallerIdentity.get();
8386        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8387            uid = tlsIdentity.uid;
8388            pid = tlsIdentity.pid;
8389        }
8390
8391        // Our own process gets to do everything.
8392        if (pid == MY_PID) {
8393            return PackageManager.PERMISSION_GRANTED;
8394        }
8395        synchronized (this) {
8396            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8397                    ? PackageManager.PERMISSION_GRANTED
8398                    : PackageManager.PERMISSION_DENIED;
8399        }
8400    }
8401
8402    /**
8403     * Check if the targetPkg can be granted permission to access uri by
8404     * the callingUid using the given modeFlags.  Throws a security exception
8405     * if callingUid is not allowed to do this.  Returns the uid of the target
8406     * if the URI permission grant should be performed; returns -1 if it is not
8407     * needed (for example targetPkg already has permission to access the URI).
8408     * If you already know the uid of the target, you can supply it in
8409     * lastTargetUid else set that to -1.
8410     */
8411    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8412            final int modeFlags, int lastTargetUid) {
8413        if (!Intent.isAccessUriMode(modeFlags)) {
8414            return -1;
8415        }
8416
8417        if (targetPkg != null) {
8418            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8419                    "Checking grant " + targetPkg + " permission to " + grantUri);
8420        }
8421
8422        final IPackageManager pm = AppGlobals.getPackageManager();
8423
8424        // If this is not a content: uri, we can't do anything with it.
8425        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8426            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8427                    "Can't grant URI permission for non-content URI: " + grantUri);
8428            return -1;
8429        }
8430
8431        final String authority = grantUri.uri.getAuthority();
8432        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8433                MATCH_DEBUG_TRIAGED_MISSING);
8434        if (pi == null) {
8435            Slog.w(TAG, "No content provider found for permission check: " +
8436                    grantUri.uri.toSafeString());
8437            return -1;
8438        }
8439
8440        int targetUid = lastTargetUid;
8441        if (targetUid < 0 && targetPkg != null) {
8442            try {
8443                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8444                        UserHandle.getUserId(callingUid));
8445                if (targetUid < 0) {
8446                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8447                            "Can't grant URI permission no uid for: " + targetPkg);
8448                    return -1;
8449                }
8450            } catch (RemoteException ex) {
8451                return -1;
8452            }
8453        }
8454
8455        // If we're extending a persistable grant, then we always need to create
8456        // the grant data structure so that take/release APIs work
8457        if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
8458            return targetUid;
8459        }
8460
8461        if (targetUid >= 0) {
8462            // First...  does the target actually need this permission?
8463            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8464                // No need to grant the target this permission.
8465                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8466                        "Target " + targetPkg + " already has full permission to " + grantUri);
8467                return -1;
8468            }
8469        } else {
8470            // First...  there is no target package, so can anyone access it?
8471            boolean allowed = pi.exported;
8472            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8473                if (pi.readPermission != null) {
8474                    allowed = false;
8475                }
8476            }
8477            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8478                if (pi.writePermission != null) {
8479                    allowed = false;
8480                }
8481            }
8482            if (allowed) {
8483                return -1;
8484            }
8485        }
8486
8487        /* There is a special cross user grant if:
8488         * - The target is on another user.
8489         * - Apps on the current user can access the uri without any uid permissions.
8490         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8491         * grant uri permissions.
8492         */
8493        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8494                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8495                modeFlags, false /*without considering the uid permissions*/);
8496
8497        // Second...  is the provider allowing granting of URI permissions?
8498        if (!specialCrossUserGrant) {
8499            if (!pi.grantUriPermissions) {
8500                throw new SecurityException("Provider " + pi.packageName
8501                        + "/" + pi.name
8502                        + " does not allow granting of Uri permissions (uri "
8503                        + grantUri + ")");
8504            }
8505            if (pi.uriPermissionPatterns != null) {
8506                final int N = pi.uriPermissionPatterns.length;
8507                boolean allowed = false;
8508                for (int i=0; i<N; i++) {
8509                    if (pi.uriPermissionPatterns[i] != null
8510                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8511                        allowed = true;
8512                        break;
8513                    }
8514                }
8515                if (!allowed) {
8516                    throw new SecurityException("Provider " + pi.packageName
8517                            + "/" + pi.name
8518                            + " does not allow granting of permission to path of Uri "
8519                            + grantUri);
8520                }
8521            }
8522        }
8523
8524        // Third...  does the caller itself have permission to access
8525        // this uri?
8526        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
8527            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8528                // Require they hold a strong enough Uri permission
8529                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8530                    throw new SecurityException("Uid " + callingUid
8531                            + " does not have permission to uri " + grantUri);
8532                }
8533            }
8534        }
8535        return targetUid;
8536    }
8537
8538    /**
8539     * @param uri This uri must NOT contain an embedded userId.
8540     * @param userId The userId in which the uri is to be resolved.
8541     */
8542    @Override
8543    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8544            final int modeFlags, int userId) {
8545        enforceNotIsolatedCaller("checkGrantUriPermission");
8546        synchronized(this) {
8547            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8548                    new GrantUri(userId, uri, false), modeFlags, -1);
8549        }
8550    }
8551
8552    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8553            final int modeFlags, UriPermissionOwner owner) {
8554        if (!Intent.isAccessUriMode(modeFlags)) {
8555            return;
8556        }
8557
8558        // So here we are: the caller has the assumed permission
8559        // to the uri, and the target doesn't.  Let's now give this to
8560        // the target.
8561
8562        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8563                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8564
8565        final String authority = grantUri.uri.getAuthority();
8566        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8567                MATCH_DEBUG_TRIAGED_MISSING);
8568        if (pi == null) {
8569            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8570            return;
8571        }
8572
8573        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8574            grantUri.prefix = true;
8575        }
8576        final UriPermission perm = findOrCreateUriPermissionLocked(
8577                pi.packageName, targetPkg, targetUid, grantUri);
8578        perm.grantModes(modeFlags, owner);
8579    }
8580
8581    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8582            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8583        if (targetPkg == null) {
8584            throw new NullPointerException("targetPkg");
8585        }
8586        int targetUid;
8587        final IPackageManager pm = AppGlobals.getPackageManager();
8588        try {
8589            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8590        } catch (RemoteException ex) {
8591            return;
8592        }
8593
8594        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8595                targetUid);
8596        if (targetUid < 0) {
8597            return;
8598        }
8599
8600        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8601                owner);
8602    }
8603
8604    static class NeededUriGrants extends ArrayList<GrantUri> {
8605        final String targetPkg;
8606        final int targetUid;
8607        final int flags;
8608
8609        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8610            this.targetPkg = targetPkg;
8611            this.targetUid = targetUid;
8612            this.flags = flags;
8613        }
8614    }
8615
8616    /**
8617     * Like checkGrantUriPermissionLocked, but takes an Intent.
8618     */
8619    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8620            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8621        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8622                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8623                + " clip=" + (intent != null ? intent.getClipData() : null)
8624                + " from " + intent + "; flags=0x"
8625                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8626
8627        if (targetPkg == null) {
8628            throw new NullPointerException("targetPkg");
8629        }
8630
8631        if (intent == null) {
8632            return null;
8633        }
8634        Uri data = intent.getData();
8635        ClipData clip = intent.getClipData();
8636        if (data == null && clip == null) {
8637            return null;
8638        }
8639        // Default userId for uris in the intent (if they don't specify it themselves)
8640        int contentUserHint = intent.getContentUserHint();
8641        if (contentUserHint == UserHandle.USER_CURRENT) {
8642            contentUserHint = UserHandle.getUserId(callingUid);
8643        }
8644        final IPackageManager pm = AppGlobals.getPackageManager();
8645        int targetUid;
8646        if (needed != null) {
8647            targetUid = needed.targetUid;
8648        } else {
8649            try {
8650                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8651                        targetUserId);
8652            } catch (RemoteException ex) {
8653                return null;
8654            }
8655            if (targetUid < 0) {
8656                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8657                        "Can't grant URI permission no uid for: " + targetPkg
8658                        + " on user " + targetUserId);
8659                return null;
8660            }
8661        }
8662        if (data != null) {
8663            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8664            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8665                    targetUid);
8666            if (targetUid > 0) {
8667                if (needed == null) {
8668                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8669                }
8670                needed.add(grantUri);
8671            }
8672        }
8673        if (clip != null) {
8674            for (int i=0; i<clip.getItemCount(); i++) {
8675                Uri uri = clip.getItemAt(i).getUri();
8676                if (uri != null) {
8677                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8678                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8679                            targetUid);
8680                    if (targetUid > 0) {
8681                        if (needed == null) {
8682                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8683                        }
8684                        needed.add(grantUri);
8685                    }
8686                } else {
8687                    Intent clipIntent = clip.getItemAt(i).getIntent();
8688                    if (clipIntent != null) {
8689                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8690                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8691                        if (newNeeded != null) {
8692                            needed = newNeeded;
8693                        }
8694                    }
8695                }
8696            }
8697        }
8698
8699        return needed;
8700    }
8701
8702    /**
8703     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8704     */
8705    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8706            UriPermissionOwner owner) {
8707        if (needed != null) {
8708            for (int i=0; i<needed.size(); i++) {
8709                GrantUri grantUri = needed.get(i);
8710                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8711                        grantUri, needed.flags, owner);
8712            }
8713        }
8714    }
8715
8716    void grantUriPermissionFromIntentLocked(int callingUid,
8717            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8718        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8719                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8720        if (needed == null) {
8721            return;
8722        }
8723
8724        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8725    }
8726
8727    /**
8728     * @param uri This uri must NOT contain an embedded userId.
8729     * @param userId The userId in which the uri is to be resolved.
8730     */
8731    @Override
8732    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8733            final int modeFlags, int userId) {
8734        enforceNotIsolatedCaller("grantUriPermission");
8735        GrantUri grantUri = new GrantUri(userId, uri, false);
8736        synchronized(this) {
8737            final ProcessRecord r = getRecordForAppLocked(caller);
8738            if (r == null) {
8739                throw new SecurityException("Unable to find app for caller "
8740                        + caller
8741                        + " when granting permission to uri " + grantUri);
8742            }
8743            if (targetPkg == null) {
8744                throw new IllegalArgumentException("null target");
8745            }
8746            if (grantUri == null) {
8747                throw new IllegalArgumentException("null uri");
8748            }
8749
8750            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8751                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8752                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8753                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8754
8755            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8756                    UserHandle.getUserId(r.uid));
8757        }
8758    }
8759
8760    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8761        if (perm.modeFlags == 0) {
8762            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8763                    perm.targetUid);
8764            if (perms != null) {
8765                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8766                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8767
8768                perms.remove(perm.uri);
8769                if (perms.isEmpty()) {
8770                    mGrantedUriPermissions.remove(perm.targetUid);
8771                }
8772            }
8773        }
8774    }
8775
8776    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8777        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8778                "Revoking all granted permissions to " + grantUri);
8779
8780        final IPackageManager pm = AppGlobals.getPackageManager();
8781        final String authority = grantUri.uri.getAuthority();
8782        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8783                MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8784        if (pi == null) {
8785            Slog.w(TAG, "No content provider found for permission revoke: "
8786                    + grantUri.toSafeString());
8787            return;
8788        }
8789
8790        // Does the caller have this permission on the URI?
8791        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8792            // If they don't have direct access to the URI, then revoke any
8793            // ownerless URI permissions that have been granted to them.
8794            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8795            if (perms != null) {
8796                boolean persistChanged = false;
8797                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8798                    final UriPermission perm = it.next();
8799                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8800                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8801                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8802                                "Revoking non-owned " + perm.targetUid
8803                                + " permission to " + perm.uri);
8804                        persistChanged |= perm.revokeModes(
8805                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8806                        if (perm.modeFlags == 0) {
8807                            it.remove();
8808                        }
8809                    }
8810                }
8811                if (perms.isEmpty()) {
8812                    mGrantedUriPermissions.remove(callingUid);
8813                }
8814                if (persistChanged) {
8815                    schedulePersistUriGrants();
8816                }
8817            }
8818            return;
8819        }
8820
8821        boolean persistChanged = false;
8822
8823        // Go through all of the permissions and remove any that match.
8824        int N = mGrantedUriPermissions.size();
8825        for (int i = 0; i < N; i++) {
8826            final int targetUid = mGrantedUriPermissions.keyAt(i);
8827            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8828
8829            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8830                final UriPermission perm = it.next();
8831                if (perm.uri.sourceUserId == grantUri.sourceUserId
8832                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8833                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8834                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8835                    persistChanged |= perm.revokeModes(
8836                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8837                    if (perm.modeFlags == 0) {
8838                        it.remove();
8839                    }
8840                }
8841            }
8842
8843            if (perms.isEmpty()) {
8844                mGrantedUriPermissions.remove(targetUid);
8845                N--;
8846                i--;
8847            }
8848        }
8849
8850        if (persistChanged) {
8851            schedulePersistUriGrants();
8852        }
8853    }
8854
8855    /**
8856     * @param uri This uri must NOT contain an embedded userId.
8857     * @param userId The userId in which the uri is to be resolved.
8858     */
8859    @Override
8860    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8861            int userId) {
8862        enforceNotIsolatedCaller("revokeUriPermission");
8863        synchronized(this) {
8864            final ProcessRecord r = getRecordForAppLocked(caller);
8865            if (r == null) {
8866                throw new SecurityException("Unable to find app for caller "
8867                        + caller
8868                        + " when revoking permission to uri " + uri);
8869            }
8870            if (uri == null) {
8871                Slog.w(TAG, "revokeUriPermission: null uri");
8872                return;
8873            }
8874
8875            if (!Intent.isAccessUriMode(modeFlags)) {
8876                return;
8877            }
8878
8879            final String authority = uri.getAuthority();
8880            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8881                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8882            if (pi == null) {
8883                Slog.w(TAG, "No content provider found for permission revoke: "
8884                        + uri.toSafeString());
8885                return;
8886            }
8887
8888            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8889        }
8890    }
8891
8892    /**
8893     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8894     * given package.
8895     *
8896     * @param packageName Package name to match, or {@code null} to apply to all
8897     *            packages.
8898     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8899     *            to all users.
8900     * @param persistable If persistable grants should be removed.
8901     */
8902    private void removeUriPermissionsForPackageLocked(
8903            String packageName, int userHandle, boolean persistable) {
8904        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8905            throw new IllegalArgumentException("Must narrow by either package or user");
8906        }
8907
8908        boolean persistChanged = false;
8909
8910        int N = mGrantedUriPermissions.size();
8911        for (int i = 0; i < N; i++) {
8912            final int targetUid = mGrantedUriPermissions.keyAt(i);
8913            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8914
8915            // Only inspect grants matching user
8916            if (userHandle == UserHandle.USER_ALL
8917                    || userHandle == UserHandle.getUserId(targetUid)) {
8918                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8919                    final UriPermission perm = it.next();
8920
8921                    // Only inspect grants matching package
8922                    if (packageName == null || perm.sourcePkg.equals(packageName)
8923                            || perm.targetPkg.equals(packageName)) {
8924                        // Hacky solution as part of fixing a security bug; ignore
8925                        // grants associated with DownloadManager so we don't have
8926                        // to immediately launch it to regrant the permissions
8927                        if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
8928                                && !persistable) continue;
8929
8930                        persistChanged |= perm.revokeModes(persistable
8931                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8932
8933                        // Only remove when no modes remain; any persisted grants
8934                        // will keep this alive.
8935                        if (perm.modeFlags == 0) {
8936                            it.remove();
8937                        }
8938                    }
8939                }
8940
8941                if (perms.isEmpty()) {
8942                    mGrantedUriPermissions.remove(targetUid);
8943                    N--;
8944                    i--;
8945                }
8946            }
8947        }
8948
8949        if (persistChanged) {
8950            schedulePersistUriGrants();
8951        }
8952    }
8953
8954    @Override
8955    public IBinder newUriPermissionOwner(String name) {
8956        enforceNotIsolatedCaller("newUriPermissionOwner");
8957        synchronized(this) {
8958            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8959            return owner.getExternalTokenLocked();
8960        }
8961    }
8962
8963    @Override
8964    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8965        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8966        synchronized(this) {
8967            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8968            if (r == null) {
8969                throw new IllegalArgumentException("Activity does not exist; token="
8970                        + activityToken);
8971            }
8972            return r.getUriPermissionsLocked().getExternalTokenLocked();
8973        }
8974    }
8975    /**
8976     * @param uri This uri must NOT contain an embedded userId.
8977     * @param sourceUserId The userId in which the uri is to be resolved.
8978     * @param targetUserId The userId of the app that receives the grant.
8979     */
8980    @Override
8981    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8982            final int modeFlags, int sourceUserId, int targetUserId) {
8983        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8984                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8985                "grantUriPermissionFromOwner", null);
8986        synchronized(this) {
8987            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8988            if (owner == null) {
8989                throw new IllegalArgumentException("Unknown owner: " + token);
8990            }
8991            if (fromUid != Binder.getCallingUid()) {
8992                if (Binder.getCallingUid() != Process.myUid()) {
8993                    // Only system code can grant URI permissions on behalf
8994                    // of other users.
8995                    throw new SecurityException("nice try");
8996                }
8997            }
8998            if (targetPkg == null) {
8999                throw new IllegalArgumentException("null target");
9000            }
9001            if (uri == null) {
9002                throw new IllegalArgumentException("null uri");
9003            }
9004
9005            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
9006                    modeFlags, owner, targetUserId);
9007        }
9008    }
9009
9010    /**
9011     * @param uri This uri must NOT contain an embedded userId.
9012     * @param userId The userId in which the uri is to be resolved.
9013     */
9014    @Override
9015    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
9016        synchronized(this) {
9017            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9018            if (owner == null) {
9019                throw new IllegalArgumentException("Unknown owner: " + token);
9020            }
9021
9022            if (uri == null) {
9023                owner.removeUriPermissionsLocked(mode);
9024            } else {
9025                final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
9026                owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
9027            }
9028        }
9029    }
9030
9031    private void schedulePersistUriGrants() {
9032        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
9033            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
9034                    10 * DateUtils.SECOND_IN_MILLIS);
9035        }
9036    }
9037
9038    private void writeGrantedUriPermissions() {
9039        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
9040
9041        // Snapshot permissions so we can persist without lock
9042        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
9043        synchronized (this) {
9044            final int size = mGrantedUriPermissions.size();
9045            for (int i = 0; i < size; i++) {
9046                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9047                for (UriPermission perm : perms.values()) {
9048                    if (perm.persistedModeFlags != 0) {
9049                        persist.add(perm.snapshot());
9050                    }
9051                }
9052            }
9053        }
9054
9055        FileOutputStream fos = null;
9056        try {
9057            fos = mGrantFile.startWrite();
9058
9059            XmlSerializer out = new FastXmlSerializer();
9060            out.setOutput(fos, StandardCharsets.UTF_8.name());
9061            out.startDocument(null, true);
9062            out.startTag(null, TAG_URI_GRANTS);
9063            for (UriPermission.Snapshot perm : persist) {
9064                out.startTag(null, TAG_URI_GRANT);
9065                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
9066                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
9067                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
9068                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
9069                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
9070                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
9071                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
9072                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
9073                out.endTag(null, TAG_URI_GRANT);
9074            }
9075            out.endTag(null, TAG_URI_GRANTS);
9076            out.endDocument();
9077
9078            mGrantFile.finishWrite(fos);
9079        } catch (IOException e) {
9080            if (fos != null) {
9081                mGrantFile.failWrite(fos);
9082            }
9083        }
9084    }
9085
9086    private void readGrantedUriPermissionsLocked() {
9087        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
9088
9089        final long now = System.currentTimeMillis();
9090
9091        FileInputStream fis = null;
9092        try {
9093            fis = mGrantFile.openRead();
9094            final XmlPullParser in = Xml.newPullParser();
9095            in.setInput(fis, StandardCharsets.UTF_8.name());
9096
9097            int type;
9098            while ((type = in.next()) != END_DOCUMENT) {
9099                final String tag = in.getName();
9100                if (type == START_TAG) {
9101                    if (TAG_URI_GRANT.equals(tag)) {
9102                        final int sourceUserId;
9103                        final int targetUserId;
9104                        final int userHandle = readIntAttribute(in,
9105                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
9106                        if (userHandle != UserHandle.USER_NULL) {
9107                            // For backwards compatibility.
9108                            sourceUserId = userHandle;
9109                            targetUserId = userHandle;
9110                        } else {
9111                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
9112                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
9113                        }
9114                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
9115                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
9116                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
9117                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
9118                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
9119                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
9120
9121                        // Sanity check that provider still belongs to source package
9122                        // Both direct boot aware and unaware packages are fine as we
9123                        // will do filtering at query time to avoid multiple parsing.
9124                        final ProviderInfo pi = getProviderInfoLocked(
9125                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
9126                                        | MATCH_DIRECT_BOOT_UNAWARE);
9127                        if (pi != null && sourcePkg.equals(pi.packageName)) {
9128                            int targetUid = -1;
9129                            try {
9130                                targetUid = AppGlobals.getPackageManager().getPackageUid(
9131                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
9132                            } catch (RemoteException e) {
9133                            }
9134                            if (targetUid != -1) {
9135                                final UriPermission perm = findOrCreateUriPermissionLocked(
9136                                        sourcePkg, targetPkg, targetUid,
9137                                        new GrantUri(sourceUserId, uri, prefix));
9138                                perm.initPersistedModes(modeFlags, createdTime);
9139                            }
9140                        } else {
9141                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
9142                                    + " but instead found " + pi);
9143                        }
9144                    }
9145                }
9146            }
9147        } catch (FileNotFoundException e) {
9148            // Missing grants is okay
9149        } catch (IOException e) {
9150            Slog.wtf(TAG, "Failed reading Uri grants", e);
9151        } catch (XmlPullParserException e) {
9152            Slog.wtf(TAG, "Failed reading Uri grants", e);
9153        } finally {
9154            IoUtils.closeQuietly(fis);
9155        }
9156    }
9157
9158    /**
9159     * @param uri This uri must NOT contain an embedded userId.
9160     * @param userId The userId in which the uri is to be resolved.
9161     */
9162    @Override
9163    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9164        enforceNotIsolatedCaller("takePersistableUriPermission");
9165
9166        Preconditions.checkFlagsArgument(modeFlags,
9167                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9168
9169        synchronized (this) {
9170            final int callingUid = Binder.getCallingUid();
9171            boolean persistChanged = false;
9172            GrantUri grantUri = new GrantUri(userId, uri, false);
9173
9174            UriPermission exactPerm = findUriPermissionLocked(callingUid,
9175                    new GrantUri(userId, uri, false));
9176            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9177                    new GrantUri(userId, uri, true));
9178
9179            final boolean exactValid = (exactPerm != null)
9180                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
9181            final boolean prefixValid = (prefixPerm != null)
9182                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
9183
9184            if (!(exactValid || prefixValid)) {
9185                throw new SecurityException("No persistable permission grants found for UID "
9186                        + callingUid + " and Uri " + grantUri.toSafeString());
9187            }
9188
9189            if (exactValid) {
9190                persistChanged |= exactPerm.takePersistableModes(modeFlags);
9191            }
9192            if (prefixValid) {
9193                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
9194            }
9195
9196            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
9197
9198            if (persistChanged) {
9199                schedulePersistUriGrants();
9200            }
9201        }
9202    }
9203
9204    /**
9205     * @param uri This uri must NOT contain an embedded userId.
9206     * @param userId The userId in which the uri is to be resolved.
9207     */
9208    @Override
9209    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9210        enforceNotIsolatedCaller("releasePersistableUriPermission");
9211
9212        Preconditions.checkFlagsArgument(modeFlags,
9213                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9214
9215        synchronized (this) {
9216            final int callingUid = Binder.getCallingUid();
9217            boolean persistChanged = false;
9218
9219            UriPermission exactPerm = findUriPermissionLocked(callingUid,
9220                    new GrantUri(userId, uri, false));
9221            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9222                    new GrantUri(userId, uri, true));
9223            if (exactPerm == null && prefixPerm == null) {
9224                throw new SecurityException("No permission grants found for UID " + callingUid
9225                        + " and Uri " + uri.toSafeString());
9226            }
9227
9228            if (exactPerm != null) {
9229                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
9230                removeUriPermissionIfNeededLocked(exactPerm);
9231            }
9232            if (prefixPerm != null) {
9233                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
9234                removeUriPermissionIfNeededLocked(prefixPerm);
9235            }
9236
9237            if (persistChanged) {
9238                schedulePersistUriGrants();
9239            }
9240        }
9241    }
9242
9243    /**
9244     * Prune any older {@link UriPermission} for the given UID until outstanding
9245     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
9246     *
9247     * @return if any mutations occured that require persisting.
9248     */
9249    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
9250        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
9251        if (perms == null) return false;
9252        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
9253
9254        final ArrayList<UriPermission> persisted = Lists.newArrayList();
9255        for (UriPermission perm : perms.values()) {
9256            if (perm.persistedModeFlags != 0) {
9257                persisted.add(perm);
9258            }
9259        }
9260
9261        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
9262        if (trimCount <= 0) return false;
9263
9264        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
9265        for (int i = 0; i < trimCount; i++) {
9266            final UriPermission perm = persisted.get(i);
9267
9268            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9269                    "Trimming grant created at " + perm.persistedCreateTime);
9270
9271            perm.releasePersistableModes(~0);
9272            removeUriPermissionIfNeededLocked(perm);
9273        }
9274
9275        return true;
9276    }
9277
9278    @Override
9279    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
9280            String packageName, boolean incoming) {
9281        enforceNotIsolatedCaller("getPersistedUriPermissions");
9282        Preconditions.checkNotNull(packageName, "packageName");
9283
9284        final int callingUid = Binder.getCallingUid();
9285        final int callingUserId = UserHandle.getUserId(callingUid);
9286        final IPackageManager pm = AppGlobals.getPackageManager();
9287        try {
9288            final int packageUid = pm.getPackageUid(packageName,
9289                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
9290            if (packageUid != callingUid) {
9291                throw new SecurityException(
9292                        "Package " + packageName + " does not belong to calling UID " + callingUid);
9293            }
9294        } catch (RemoteException e) {
9295            throw new SecurityException("Failed to verify package name ownership");
9296        }
9297
9298        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9299        synchronized (this) {
9300            if (incoming) {
9301                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9302                        callingUid);
9303                if (perms == null) {
9304                    Slog.w(TAG, "No permission grants found for " + packageName);
9305                } else {
9306                    for (UriPermission perm : perms.values()) {
9307                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
9308                            result.add(perm.buildPersistedPublicApiObject());
9309                        }
9310                    }
9311                }
9312            } else {
9313                final int size = mGrantedUriPermissions.size();
9314                for (int i = 0; i < size; i++) {
9315                    final ArrayMap<GrantUri, UriPermission> perms =
9316                            mGrantedUriPermissions.valueAt(i);
9317                    for (UriPermission perm : perms.values()) {
9318                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
9319                            result.add(perm.buildPersistedPublicApiObject());
9320                        }
9321                    }
9322                }
9323            }
9324        }
9325        return new ParceledListSlice<android.content.UriPermission>(result);
9326    }
9327
9328    @Override
9329    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
9330            String packageName, int userId) {
9331        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
9332                "getGrantedUriPermissions");
9333
9334        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9335        synchronized (this) {
9336            final int size = mGrantedUriPermissions.size();
9337            for (int i = 0; i < size; i++) {
9338                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9339                for (UriPermission perm : perms.values()) {
9340                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
9341                            && perm.persistedModeFlags != 0) {
9342                        result.add(perm.buildPersistedPublicApiObject());
9343                    }
9344                }
9345            }
9346        }
9347        return new ParceledListSlice<android.content.UriPermission>(result);
9348    }
9349
9350    @Override
9351    public void clearGrantedUriPermissions(String packageName, int userId) {
9352        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
9353                "clearGrantedUriPermissions");
9354        removeUriPermissionsForPackageLocked(packageName, userId, true);
9355    }
9356
9357    @Override
9358    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
9359        synchronized (this) {
9360            ProcessRecord app =
9361                who != null ? getRecordForAppLocked(who) : null;
9362            if (app == null) return;
9363
9364            Message msg = Message.obtain();
9365            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
9366            msg.obj = app;
9367            msg.arg1 = waiting ? 1 : 0;
9368            mUiHandler.sendMessage(msg);
9369        }
9370    }
9371
9372    @Override
9373    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9374        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9375        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9376        outInfo.availMem = Process.getFreeMemory();
9377        outInfo.totalMem = Process.getTotalMemory();
9378        outInfo.threshold = homeAppMem;
9379        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9380        outInfo.hiddenAppThreshold = cachedAppMem;
9381        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9382                ProcessList.SERVICE_ADJ);
9383        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9384                ProcessList.VISIBLE_APP_ADJ);
9385        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9386                ProcessList.FOREGROUND_APP_ADJ);
9387    }
9388
9389    // =========================================================
9390    // TASK MANAGEMENT
9391    // =========================================================
9392
9393    @Override
9394    public List<IBinder> getAppTasks(String callingPackage) {
9395        int callingUid = Binder.getCallingUid();
9396        long ident = Binder.clearCallingIdentity();
9397
9398        synchronized(this) {
9399            ArrayList<IBinder> list = new ArrayList<IBinder>();
9400            try {
9401                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9402
9403                final int N = mRecentTasks.size();
9404                for (int i = 0; i < N; i++) {
9405                    TaskRecord tr = mRecentTasks.get(i);
9406                    // Skip tasks that do not match the caller.  We don't need to verify
9407                    // callingPackage, because we are also limiting to callingUid and know
9408                    // that will limit to the correct security sandbox.
9409                    if (tr.effectiveUid != callingUid) {
9410                        continue;
9411                    }
9412                    Intent intent = tr.getBaseIntent();
9413                    if (intent == null ||
9414                            !callingPackage.equals(intent.getComponent().getPackageName())) {
9415                        continue;
9416                    }
9417                    ActivityManager.RecentTaskInfo taskInfo =
9418                            createRecentTaskInfoFromTaskRecord(tr);
9419                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9420                    list.add(taskImpl.asBinder());
9421                }
9422            } finally {
9423                Binder.restoreCallingIdentity(ident);
9424            }
9425            return list;
9426        }
9427    }
9428
9429    @Override
9430    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9431        final int callingUid = Binder.getCallingUid();
9432        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9433
9434        synchronized(this) {
9435            if (DEBUG_ALL) Slog.v(
9436                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9437
9438            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9439                    callingUid);
9440
9441            // TODO: Improve with MRU list from all ActivityStacks.
9442            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9443        }
9444
9445        return list;
9446    }
9447
9448    /**
9449     * Creates a new RecentTaskInfo from a TaskRecord.
9450     */
9451    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9452        // Update the task description to reflect any changes in the task stack
9453        tr.updateTaskDescription();
9454
9455        // Compose the recent task info
9456        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9457        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9458        rti.persistentId = tr.taskId;
9459        rti.baseIntent = new Intent(tr.getBaseIntent());
9460        rti.origActivity = tr.origActivity;
9461        rti.realActivity = tr.realActivity;
9462        rti.description = tr.lastDescription;
9463        rti.stackId = tr.getStackId();
9464        rti.userId = tr.userId;
9465        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9466        rti.firstActiveTime = tr.firstActiveTime;
9467        rti.lastActiveTime = tr.lastActiveTime;
9468        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9469        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9470        rti.numActivities = 0;
9471        if (tr.mBounds != null) {
9472            rti.bounds = new Rect(tr.mBounds);
9473        }
9474        rti.supportsSplitScreenMultiWindow = tr.supportsSplitScreen();
9475        rti.resizeMode = tr.mResizeMode;
9476
9477        ActivityRecord base = null;
9478        ActivityRecord top = null;
9479        ActivityRecord tmp;
9480
9481        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9482            tmp = tr.mActivities.get(i);
9483            if (tmp.finishing) {
9484                continue;
9485            }
9486            base = tmp;
9487            if (top == null || (top.state == ActivityState.INITIALIZING)) {
9488                top = base;
9489            }
9490            rti.numActivities++;
9491        }
9492
9493        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9494        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9495
9496        return rti;
9497    }
9498
9499    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9500        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9501                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9502        if (!allowed) {
9503            if (checkPermission(android.Manifest.permission.GET_TASKS,
9504                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9505                // Temporary compatibility: some existing apps on the system image may
9506                // still be requesting the old permission and not switched to the new
9507                // one; if so, we'll still allow them full access.  This means we need
9508                // to see if they are holding the old permission and are a system app.
9509                try {
9510                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9511                        allowed = true;
9512                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9513                                + " is using old GET_TASKS but privileged; allowing");
9514                    }
9515                } catch (RemoteException e) {
9516                }
9517            }
9518        }
9519        if (!allowed) {
9520            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9521                    + " does not hold REAL_GET_TASKS; limiting output");
9522        }
9523        return allowed;
9524    }
9525
9526    @Override
9527    public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9528            int userId) {
9529        final int callingUid = Binder.getCallingUid();
9530        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9531                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9532
9533        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9534        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9535        synchronized (this) {
9536            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9537                    callingUid);
9538            final boolean detailed = checkCallingPermission(
9539                    android.Manifest.permission.GET_DETAILED_TASKS)
9540                    == PackageManager.PERMISSION_GRANTED;
9541
9542            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9543                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9544                return ParceledListSlice.emptyList();
9545            }
9546            mRecentTasks.loadUserRecentsLocked(userId);
9547
9548            final int recentsCount = mRecentTasks.size();
9549            ArrayList<ActivityManager.RecentTaskInfo> res =
9550                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9551
9552            final Set<Integer> includedUsers;
9553            if (includeProfiles) {
9554                includedUsers = mUserController.getProfileIds(userId);
9555            } else {
9556                includedUsers = new HashSet<>();
9557            }
9558            includedUsers.add(Integer.valueOf(userId));
9559
9560            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9561                TaskRecord tr = mRecentTasks.get(i);
9562                // Only add calling user or related users recent tasks
9563                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9564                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9565                    continue;
9566                }
9567
9568                if (tr.realActivitySuspended) {
9569                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9570                    continue;
9571                }
9572
9573                // Return the entry if desired by the caller.  We always return
9574                // the first entry, because callers always expect this to be the
9575                // foreground app.  We may filter others if the caller has
9576                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9577                // we should exclude the entry.
9578
9579                if (i == 0
9580                        || withExcluded
9581                        || (tr.intent == null)
9582                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9583                                == 0)) {
9584                    if (!allowed) {
9585                        // If the caller doesn't have the GET_TASKS permission, then only
9586                        // allow them to see a small subset of tasks -- their own and home.
9587                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9588                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9589                            continue;
9590                        }
9591                    }
9592                    final ActivityStack stack = tr.getStack();
9593                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS) != 0) {
9594                        if (stack != null && stack.isHomeOrRecentsStack()) {
9595                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9596                                    "Skipping, home or recents stack task: " + tr);
9597                            continue;
9598                        }
9599                    }
9600                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9601                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9602                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9603                                    "Skipping, top task in docked stack: " + tr);
9604                            continue;
9605                        }
9606                    }
9607                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9608                        if (stack != null && stack.isPinnedStack()) {
9609                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9610                                    "Skipping, pinned stack task: " + tr);
9611                            continue;
9612                        }
9613                    }
9614                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9615                        // Don't include auto remove tasks that are finished or finishing.
9616                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9617                                "Skipping, auto-remove without activity: " + tr);
9618                        continue;
9619                    }
9620                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9621                            && !tr.isAvailable) {
9622                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9623                                "Skipping, unavail real act: " + tr);
9624                        continue;
9625                    }
9626
9627                    if (!tr.mUserSetupComplete) {
9628                        // Don't include task launched while user is not done setting-up.
9629                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9630                                "Skipping, user setup not complete: " + tr);
9631                        continue;
9632                    }
9633
9634                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9635                    if (!detailed) {
9636                        rti.baseIntent.replaceExtras((Bundle)null);
9637                    }
9638
9639                    res.add(rti);
9640                    maxNum--;
9641                }
9642            }
9643            return new ParceledListSlice<>(res);
9644        }
9645    }
9646
9647    @Override
9648    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9649        synchronized (this) {
9650            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9651                    "getTaskThumbnail()");
9652            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9653                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9654            if (tr != null) {
9655                return tr.getTaskThumbnailLocked();
9656            }
9657        }
9658        return null;
9659    }
9660
9661    @Override
9662    public ActivityManager.TaskDescription getTaskDescription(int id) {
9663        synchronized (this) {
9664            enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9665                    "getTaskDescription()");
9666            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9667                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9668            if (tr != null) {
9669                return tr.lastTaskDescription;
9670            }
9671        }
9672        return null;
9673    }
9674
9675    @Override
9676    public int addAppTask(IBinder activityToken, Intent intent,
9677            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9678        final int callingUid = Binder.getCallingUid();
9679        final long callingIdent = Binder.clearCallingIdentity();
9680
9681        try {
9682            synchronized (this) {
9683                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9684                if (r == null) {
9685                    throw new IllegalArgumentException("Activity does not exist; token="
9686                            + activityToken);
9687                }
9688                ComponentName comp = intent.getComponent();
9689                if (comp == null) {
9690                    throw new IllegalArgumentException("Intent " + intent
9691                            + " must specify explicit component");
9692                }
9693                if (thumbnail.getWidth() != mThumbnailWidth
9694                        || thumbnail.getHeight() != mThumbnailHeight) {
9695                    throw new IllegalArgumentException("Bad thumbnail size: got "
9696                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9697                            + mThumbnailWidth + "x" + mThumbnailHeight);
9698                }
9699                if (intent.getSelector() != null) {
9700                    intent.setSelector(null);
9701                }
9702                if (intent.getSourceBounds() != null) {
9703                    intent.setSourceBounds(null);
9704                }
9705                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9706                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9707                        // The caller has added this as an auto-remove task...  that makes no
9708                        // sense, so turn off auto-remove.
9709                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9710                    }
9711                }
9712                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9713                    mLastAddedTaskActivity = null;
9714                }
9715                ActivityInfo ainfo = mLastAddedTaskActivity;
9716                if (ainfo == null) {
9717                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9718                            comp, 0, UserHandle.getUserId(callingUid));
9719                    if (ainfo.applicationInfo.uid != callingUid) {
9720                        throw new SecurityException(
9721                                "Can't add task for another application: target uid="
9722                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9723                    }
9724                }
9725
9726                TaskRecord task = new TaskRecord(this,
9727                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9728                        ainfo, intent, description, new TaskThumbnailInfo());
9729
9730                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9731                if (trimIdx >= 0) {
9732                    // If this would have caused a trim, then we'll abort because that
9733                    // means it would be added at the end of the list but then just removed.
9734                    return INVALID_TASK_ID;
9735                }
9736
9737                final int N = mRecentTasks.size();
9738                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9739                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9740                    tr.removedFromRecents();
9741                }
9742
9743                task.inRecents = true;
9744                mRecentTasks.add(task);
9745                r.getStack().addTask(task, false, "addAppTask");
9746
9747                task.setLastThumbnailLocked(thumbnail);
9748                task.freeLastThumbnail();
9749                return task.taskId;
9750            }
9751        } finally {
9752            Binder.restoreCallingIdentity(callingIdent);
9753        }
9754    }
9755
9756    @Override
9757    public Point getAppTaskThumbnailSize() {
9758        synchronized (this) {
9759            return new Point(mThumbnailWidth,  mThumbnailHeight);
9760        }
9761    }
9762
9763    @Override
9764    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9765        synchronized (this) {
9766            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9767            if (r != null) {
9768                r.setTaskDescription(td);
9769                r.task.updateTaskDescription();
9770                mTaskChangeNotificationController.notifyTaskDescriptionChanged(r.task.taskId, td);
9771            }
9772        }
9773    }
9774
9775    @Override
9776    public void setTaskResizeable(int taskId, int resizeableMode) {
9777        synchronized (this) {
9778            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9779                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9780            if (task == null) {
9781                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9782                return;
9783            }
9784            task.setResizeMode(resizeableMode);
9785        }
9786    }
9787
9788    @Override
9789    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9790        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9791        long ident = Binder.clearCallingIdentity();
9792        try {
9793            synchronized (this) {
9794                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9795                if (task == null) {
9796                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9797                    return;
9798                }
9799                // Place the task in the right stack if it isn't there already based on
9800                // the requested bounds.
9801                // The stack transition logic is:
9802                // - a null bounds on a freeform task moves that task to fullscreen
9803                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9804                //   that task to freeform
9805                // - otherwise the task is not moved
9806                int stackId = task.getStackId();
9807                if (!StackId.isTaskResizeAllowed(stackId)) {
9808                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9809                }
9810                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9811                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9812                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9813                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9814                }
9815
9816                // Reparent the task to the right stack if necessary
9817                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9818                if (stackId != task.getStackId()) {
9819                    // Defer resume until the task is resized below
9820                    task.reparent(stackId, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
9821                            DEFER_RESUME, "resizeTask");
9822                    preserveWindow = false;
9823                }
9824
9825                // After reparenting (which only resizes the task to the stack bounds), resize the
9826                // task to the actual bounds provided
9827                task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
9828            }
9829        } finally {
9830            Binder.restoreCallingIdentity(ident);
9831        }
9832    }
9833
9834    @Override
9835    public Rect getTaskBounds(int taskId) {
9836        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9837        long ident = Binder.clearCallingIdentity();
9838        Rect rect = new Rect();
9839        try {
9840            synchronized (this) {
9841                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9842                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9843                if (task == null) {
9844                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9845                    return rect;
9846                }
9847                if (task.getStack() != null) {
9848                    // Return the bounds from window manager since it will be adjusted for various
9849                    // things like the presense of a docked stack for tasks that aren't resizeable.
9850                    task.getWindowContainerBounds(rect);
9851                } else {
9852                    // Task isn't in window manager yet since it isn't associated with a stack.
9853                    // Return the persist value from activity manager
9854                    if (task.mBounds != null) {
9855                        rect.set(task.mBounds);
9856                    } else if (task.mLastNonFullscreenBounds != null) {
9857                        rect.set(task.mLastNonFullscreenBounds);
9858                    }
9859                }
9860            }
9861        } finally {
9862            Binder.restoreCallingIdentity(ident);
9863        }
9864        return rect;
9865    }
9866
9867    @Override
9868    public void cancelTaskWindowTransition(int taskId) {
9869        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskWindowTransition()");
9870        final long ident = Binder.clearCallingIdentity();
9871        try {
9872            synchronized (this) {
9873                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9874                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9875                if (task == null) {
9876                    Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
9877                    return;
9878                }
9879                task.cancelWindowTransition();
9880            }
9881        } finally {
9882            Binder.restoreCallingIdentity(ident);
9883        }
9884    }
9885
9886    @Override
9887    public void cancelTaskThumbnailTransition(int taskId) {
9888        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskThumbnailTransition()");
9889        final long ident = Binder.clearCallingIdentity();
9890        try {
9891            synchronized (this) {
9892                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9893                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9894                if (task == null) {
9895                    Slog.w(TAG, "cancelTaskThumbnailTransition: taskId=" + taskId + " not found");
9896                    return;
9897                }
9898                task.cancelThumbnailTransition();
9899            }
9900        } finally {
9901            Binder.restoreCallingIdentity(ident);
9902        }
9903    }
9904
9905    @Override
9906    public TaskSnapshot getTaskSnapshot(int taskId) {
9907        enforceCallingPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
9908        final long ident = Binder.clearCallingIdentity();
9909        try {
9910            final TaskRecord task;
9911            synchronized (this) {
9912                task = mStackSupervisor.anyTaskForIdLocked(
9913                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9914                if (task == null) {
9915                    Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
9916                    return null;
9917                }
9918            }
9919            // Don't call this while holding the lock as this operation might hit the disk.
9920            return task.getSnapshot();
9921        } finally {
9922            Binder.restoreCallingIdentity(ident);
9923        }
9924    }
9925
9926    @Override
9927    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9928        if (userId != UserHandle.getCallingUserId()) {
9929            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9930                    "getTaskDescriptionIcon");
9931        }
9932        final File passedIconFile = new File(filePath);
9933        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9934                passedIconFile.getName());
9935        if (!legitIconFile.getPath().equals(filePath)
9936                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9937            throw new IllegalArgumentException("Bad file path: " + filePath
9938                    + " passed for userId " + userId);
9939        }
9940        return mRecentTasks.getTaskDescriptionIcon(filePath);
9941    }
9942
9943    @Override
9944    public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
9945            throws RemoteException {
9946        final ActivityOptions activityOptions = ActivityOptions.fromBundle(opts);
9947        if (activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9948                activityOptions.getCustomInPlaceResId() == 0) {
9949            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9950                    "with valid animation");
9951        }
9952        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9953        mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
9954                activityOptions.getCustomInPlaceResId());
9955        mWindowManager.executeAppTransition();
9956    }
9957
9958    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9959        // Remove all tasks with activities in the specified package from the list of recent tasks
9960        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9961            TaskRecord tr = mRecentTasks.get(i);
9962            if (tr.userId != userId) continue;
9963
9964            ComponentName cn = tr.intent.getComponent();
9965            if (cn != null && cn.getPackageName().equals(packageName)) {
9966                // If the package name matches, remove the task.
9967                mStackSupervisor.removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9968            }
9969        }
9970    }
9971
9972    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9973            int userId) {
9974
9975        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9976            TaskRecord tr = mRecentTasks.get(i);
9977            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9978                continue;
9979            }
9980
9981            ComponentName cn = tr.intent.getComponent();
9982            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9983                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9984            if (sameComponent) {
9985                mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9986            }
9987        }
9988    }
9989
9990    @Override
9991    public void removeStack(int stackId) {
9992        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9993        if (StackId.isHomeOrRecentsStack(stackId)) {
9994            throw new IllegalArgumentException("Removing home or recents stack is not allowed.");
9995        }
9996
9997        synchronized (this) {
9998            final long ident = Binder.clearCallingIdentity();
9999            try {
10000                mStackSupervisor.removeStackLocked(stackId);
10001            } finally {
10002                Binder.restoreCallingIdentity(ident);
10003            }
10004        }
10005    }
10006
10007    @Override
10008    public void moveStackToDisplay(int stackId, int displayId) {
10009        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveStackToDisplay()");
10010
10011        synchronized (this) {
10012            final long ident = Binder.clearCallingIdentity();
10013            try {
10014                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
10015                        + " to displayId=" + displayId);
10016                mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
10017            } finally {
10018                Binder.restoreCallingIdentity(ident);
10019            }
10020        }
10021    }
10022
10023    @Override
10024    public boolean removeTask(int taskId) {
10025        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
10026        synchronized (this) {
10027            final long ident = Binder.clearCallingIdentity();
10028            try {
10029                return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
10030            } finally {
10031                Binder.restoreCallingIdentity(ident);
10032            }
10033        }
10034    }
10035
10036    /**
10037     * TODO: Add mController hook
10038     */
10039    @Override
10040    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
10041        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
10042
10043        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
10044        synchronized(this) {
10045            moveTaskToFrontLocked(taskId, flags, bOptions);
10046        }
10047    }
10048
10049    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
10050        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
10051
10052        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10053                Binder.getCallingUid(), -1, -1, "Task to front")) {
10054            ActivityOptions.abort(options);
10055            return;
10056        }
10057        final long origId = Binder.clearCallingIdentity();
10058        try {
10059            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10060            if (task == null) {
10061                Slog.d(TAG, "Could not find task for id: "+ taskId);
10062                return;
10063            }
10064            if (mStackSupervisor.isLockTaskModeViolation(task)) {
10065                mStackSupervisor.showLockTaskToast();
10066                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
10067                return;
10068            }
10069            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
10070            if (prev != null) {
10071                task.setTaskToReturnTo(prev);
10072            }
10073            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
10074                    false /* forceNonResizable */);
10075
10076            final ActivityRecord topActivity = task.getTopActivity();
10077            if (topActivity != null) {
10078
10079                // We are reshowing a task, use a starting window to hide the initial draw delay
10080                // so the transition can start earlier.
10081                topActivity.showStartingWindow(null /* prev */, false /* newTask */,
10082                        true /* taskSwitch */);
10083            }
10084        } finally {
10085            Binder.restoreCallingIdentity(origId);
10086        }
10087        ActivityOptions.abort(options);
10088    }
10089
10090    /**
10091     * Moves an activity, and all of the other activities within the same task, to the bottom
10092     * of the history stack.  The activity's order within the task is unchanged.
10093     *
10094     * @param token A reference to the activity we wish to move
10095     * @param nonRoot If false then this only works if the activity is the root
10096     *                of a task; if true it will work for any activity in a task.
10097     * @return Returns true if the move completed, false if not.
10098     */
10099    @Override
10100    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
10101        enforceNotIsolatedCaller("moveActivityTaskToBack");
10102        synchronized(this) {
10103            final long origId = Binder.clearCallingIdentity();
10104            try {
10105                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
10106                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10107                if (task != null) {
10108                    if (mStackSupervisor.isLockedTask(task)) {
10109                        mStackSupervisor.showLockTaskToast();
10110                        return false;
10111                    }
10112                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
10113                }
10114            } finally {
10115                Binder.restoreCallingIdentity(origId);
10116            }
10117        }
10118        return false;
10119    }
10120
10121    @Override
10122    public void moveTaskBackwards(int task) {
10123        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
10124                "moveTaskBackwards()");
10125
10126        synchronized(this) {
10127            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10128                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
10129                return;
10130            }
10131            final long origId = Binder.clearCallingIdentity();
10132            moveTaskBackwardsLocked(task);
10133            Binder.restoreCallingIdentity(origId);
10134        }
10135    }
10136
10137    private final void moveTaskBackwardsLocked(int task) {
10138        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
10139    }
10140
10141    @Override
10142    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
10143            IActivityContainerCallback callback) throws RemoteException {
10144        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
10145        synchronized (this) {
10146            if (parentActivityToken == null) {
10147                throw new IllegalArgumentException("parent token must not be null");
10148            }
10149            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
10150            if (r == null) {
10151                return null;
10152            }
10153            if (callback == null) {
10154                throw new IllegalArgumentException("callback must not be null");
10155            }
10156            return mStackSupervisor.createVirtualActivityContainer(r, callback);
10157        }
10158    }
10159
10160    @Override
10161    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
10162        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
10163        synchronized (this) {
10164            final int stackId = mStackSupervisor.getNextStackId();
10165            final ActivityStack stack =
10166                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
10167            if (stack == null) {
10168                return null;
10169            }
10170            return stack.mActivityContainer;
10171        }
10172    }
10173
10174    @Override
10175    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
10176        synchronized (this) {
10177            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
10178            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
10179                return stack.mActivityContainer.getDisplayId();
10180            }
10181            return DEFAULT_DISPLAY;
10182        }
10183    }
10184
10185    @Override
10186    public int getActivityStackId(IBinder token) throws RemoteException {
10187        synchronized (this) {
10188            ActivityStack stack = ActivityRecord.getStackLocked(token);
10189            if (stack == null) {
10190                return INVALID_STACK_ID;
10191            }
10192            return stack.mStackId;
10193        }
10194    }
10195
10196    @Override
10197    public void exitFreeformMode(IBinder token) throws RemoteException {
10198        synchronized (this) {
10199            long ident = Binder.clearCallingIdentity();
10200            try {
10201                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10202                if (r == null) {
10203                    throw new IllegalArgumentException(
10204                            "exitFreeformMode: No activity record matching token=" + token);
10205                }
10206
10207                final ActivityStack stack = r.getStack();
10208                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
10209                    throw new IllegalStateException(
10210                            "exitFreeformMode: You can only go fullscreen from freeform.");
10211                }
10212
10213                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
10214                r.task.reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT,
10215                        ANIMATE, !DEFER_RESUME, "exitFreeformMode");
10216            } finally {
10217                Binder.restoreCallingIdentity(ident);
10218            }
10219        }
10220    }
10221
10222    @Override
10223    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
10224        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
10225        if (StackId.isHomeOrRecentsStack(stackId)) {
10226            throw new IllegalArgumentException(
10227                    "moveTaskToStack: Attempt to move task " + taskId + " to stack " + stackId);
10228        }
10229        synchronized (this) {
10230            long ident = Binder.clearCallingIdentity();
10231            try {
10232                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10233                if (task == null) {
10234                    Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
10235                    return;
10236                }
10237
10238                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
10239                        + " to stackId=" + stackId + " toTop=" + toTop);
10240                if (stackId == DOCKED_STACK_ID) {
10241                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
10242                            null /* initialBounds */);
10243                }
10244
10245                final boolean successful = task.reparent(stackId, toTop,
10246                        REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "moveTaskToStack");
10247                if (successful && stackId == DOCKED_STACK_ID) {
10248                    // If task moved to docked stack - show recents if needed.
10249                    mWindowManager.showRecentApps(false /* fromHome */);
10250                }
10251            } finally {
10252                Binder.restoreCallingIdentity(ident);
10253            }
10254        }
10255    }
10256
10257    @Override
10258    public void swapDockedAndFullscreenStack() throws RemoteException {
10259        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
10260        synchronized (this) {
10261            long ident = Binder.clearCallingIdentity();
10262            try {
10263                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
10264                        FULLSCREEN_WORKSPACE_STACK_ID);
10265                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
10266                        : null;
10267                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
10268                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
10269                        : null;
10270                if (topTask == null || tasks == null || tasks.size() == 0) {
10271                    Slog.w(TAG,
10272                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
10273                    return;
10274                }
10275
10276                // TODO: App transition
10277                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
10278
10279                // Defer the resume until we move all the docked tasks to the fullscreen stack below
10280                topTask.reparent(DOCKED_STACK_ID, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10281                        DEFER_RESUME, "swapDockedAndFullscreenStack - DOCKED_STACK");
10282                final int size = tasks.size();
10283                for (int i = 0; i < size; i++) {
10284                    final int id = tasks.get(i).taskId;
10285                    if (id == topTask.taskId) {
10286                        continue;
10287                    }
10288
10289                    // Defer the resume until after all the tasks have been moved
10290                    tasks.get(i).reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10291                            REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, DEFER_RESUME,
10292                            "swapDockedAndFullscreenStack - FULLSCREEN_STACK");
10293                }
10294
10295                // Because we deferred the resume to avoid conflicts with stack switches while
10296                // resuming, we need to do it after all the tasks are moved.
10297                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10298                mStackSupervisor.resumeFocusedStackTopActivityLocked();
10299
10300                mWindowManager.executeAppTransition();
10301            } finally {
10302                Binder.restoreCallingIdentity(ident);
10303            }
10304        }
10305    }
10306
10307    /**
10308     * Moves the input task to the docked stack.
10309     *
10310     * @param taskId Id of task to move.
10311     * @param createMode The mode the docked stack should be created in if it doesn't exist
10312     *                   already. See
10313     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
10314     *                   and
10315     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
10316     * @param toTop If the task and stack should be moved to the top.
10317     * @param animate Whether we should play an animation for the moving the task
10318     * @param initialBounds If the docked stack gets created, it will use these bounds for the
10319     *                      docked stack. Pass {@code null} to use default bounds.
10320     */
10321    @Override
10322    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
10323            Rect initialBounds, boolean moveHomeStackFront) {
10324        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
10325        synchronized (this) {
10326            long ident = Binder.clearCallingIdentity();
10327            try {
10328                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10329                if (task == null) {
10330                    Slog.w(TAG, "moveTaskToDockedStack: No task for id=" + taskId);
10331                    return false;
10332                }
10333
10334                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
10335                        + " to createMode=" + createMode + " toTop=" + toTop);
10336                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10337
10338                // Defer resuming until we move the home stack to the front below
10339                final boolean moved = task.reparent(DOCKED_STACK_ID, toTop,
10340                        REPARENT_KEEP_STACK_AT_FRONT, animate, DEFER_RESUME,
10341                        "moveTaskToDockedStack");
10342                if (moved) {
10343                    if (moveHomeStackFront) {
10344                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
10345                    }
10346                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10347                }
10348                return moved;
10349            } finally {
10350                Binder.restoreCallingIdentity(ident);
10351            }
10352        }
10353    }
10354
10355    /**
10356     * Moves the top activity in the input stackId to the pinned stack.
10357     *
10358     * @param stackId Id of stack to move the top activity to pinned stack.
10359     * @param bounds Bounds to use for pinned stack.
10360     *
10361     * @return True if the top activity of the input stack was successfully moved to the pinned
10362     *          stack.
10363     */
10364    @Override
10365    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10366        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10367        synchronized (this) {
10368            if (!mSupportsPictureInPicture) {
10369                throw new IllegalStateException("moveTopActivityToPinnedStack:"
10370                        + "Device doesn't support picture-in-pciture mode");
10371            }
10372
10373            long ident = Binder.clearCallingIdentity();
10374            try {
10375                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10376            } finally {
10377                Binder.restoreCallingIdentity(ident);
10378            }
10379        }
10380    }
10381
10382    @Override
10383    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
10384            boolean preserveWindows, boolean animate, int animationDuration) {
10385        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10386        long ident = Binder.clearCallingIdentity();
10387        try {
10388            synchronized (this) {
10389                if (animate) {
10390                    if (stackId == PINNED_STACK_ID) {
10391                        final PinnedActivityStack pinnedStack =
10392                                mStackSupervisor.getStack(PINNED_STACK_ID);
10393                        pinnedStack.animateResizePinnedStack(bounds, animationDuration);
10394                    } else {
10395                        throw new IllegalArgumentException("Stack: " + stackId
10396                                + " doesn't support animated resize.");
10397                    }
10398                } else {
10399                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
10400                            null /* tempTaskInsetBounds */, preserveWindows,
10401                            allowResizeInDockedMode, !DEFER_RESUME);
10402                }
10403            }
10404        } finally {
10405            Binder.restoreCallingIdentity(ident);
10406        }
10407    }
10408
10409    @Override
10410    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10411            Rect tempDockedTaskInsetBounds,
10412            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10413        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10414                "resizeDockedStack()");
10415        long ident = Binder.clearCallingIdentity();
10416        try {
10417            synchronized (this) {
10418                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10419                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10420                        PRESERVE_WINDOWS);
10421            }
10422        } finally {
10423            Binder.restoreCallingIdentity(ident);
10424        }
10425    }
10426
10427    @Override
10428    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10429        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10430                "resizePinnedStack()");
10431        final long ident = Binder.clearCallingIdentity();
10432        try {
10433            synchronized (this) {
10434                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10435            }
10436        } finally {
10437            Binder.restoreCallingIdentity(ident);
10438        }
10439    }
10440
10441    /**
10442     * Try to place task to provided position. The final position might be different depending on
10443     * current user and stacks state. The task will be moved to target stack if it's currently in
10444     * different stack.
10445     */
10446    @Override
10447    public void positionTaskInStack(int taskId, int stackId, int position) {
10448        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10449        if (StackId.isHomeOrRecentsStack(stackId)) {
10450            throw new IllegalArgumentException(
10451                    "positionTaskInStack: Attempt to change the position of task "
10452                    + taskId + " in/to home/recents stack");
10453        }
10454        synchronized (this) {
10455            long ident = Binder.clearCallingIdentity();
10456            try {
10457                if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
10458                        + taskId + " in stackId=" + stackId + " at position=" + position);
10459                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10460                if (task == null) {
10461                    throw new IllegalArgumentException("positionTaskInStack: no task for id="
10462                            + taskId);
10463                }
10464
10465                final ActivityStack stack = mStackSupervisor.getStack(stackId, CREATE_IF_NEEDED,
10466                        !ON_TOP);
10467
10468                // TODO: Have the callers of this API call a separate reparent method if that is
10469                // what they intended to do vs. having this method also do reparenting.
10470                if (task.getStack() == stack) {
10471                    // Change position in current stack.
10472                    stack.positionChildAt(task, position);
10473                } else {
10474                    // Reparent to new stack.
10475                    task.reparent(stackId, position, REPARENT_LEAVE_STACK_IN_PLACE,
10476                            !ANIMATE, !DEFER_RESUME, "positionTaskInStack");
10477                }
10478            } finally {
10479                Binder.restoreCallingIdentity(ident);
10480            }
10481        }
10482    }
10483
10484    @Override
10485    public List<StackInfo> getAllStackInfos() {
10486        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10487        long ident = Binder.clearCallingIdentity();
10488        try {
10489            synchronized (this) {
10490                return mStackSupervisor.getAllStackInfosLocked();
10491            }
10492        } finally {
10493            Binder.restoreCallingIdentity(ident);
10494        }
10495    }
10496
10497    @Override
10498    public StackInfo getStackInfo(int stackId) {
10499        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10500        long ident = Binder.clearCallingIdentity();
10501        try {
10502            synchronized (this) {
10503                return mStackSupervisor.getStackInfoLocked(stackId);
10504            }
10505        } finally {
10506            Binder.restoreCallingIdentity(ident);
10507        }
10508    }
10509
10510    @Override
10511    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10512        synchronized(this) {
10513            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10514        }
10515    }
10516
10517    @Override
10518    public void updateDeviceOwner(String packageName) {
10519        final int callingUid = Binder.getCallingUid();
10520        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10521            throw new SecurityException("updateDeviceOwner called from non-system process");
10522        }
10523        synchronized (this) {
10524            mDeviceOwnerName = packageName;
10525        }
10526    }
10527
10528    @Override
10529    public void updateLockTaskPackages(int userId, String[] packages) {
10530        final int callingUid = Binder.getCallingUid();
10531        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10532            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10533                    "updateLockTaskPackages()");
10534        }
10535        synchronized (this) {
10536            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10537                    Arrays.toString(packages));
10538            mLockTaskPackages.put(userId, packages);
10539            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10540        }
10541    }
10542
10543
10544    void startLockTaskModeLocked(TaskRecord task) {
10545        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10546        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10547            return;
10548        }
10549
10550        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10551        // is initiated by system after the pinning request was shown and locked mode is initiated
10552        // by an authorized app directly
10553        final int callingUid = Binder.getCallingUid();
10554        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10555        long ident = Binder.clearCallingIdentity();
10556        try {
10557            if (!isSystemInitiated) {
10558                task.mLockTaskUid = callingUid;
10559                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10560                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10561                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10562                    StatusBarManagerInternal statusBarManager =
10563                            LocalServices.getService(StatusBarManagerInternal.class);
10564                    if (statusBarManager != null) {
10565                        statusBarManager.showScreenPinningRequest(task.taskId);
10566                    }
10567                    return;
10568                }
10569
10570                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10571                if (stack == null || task != stack.topTask()) {
10572                    throw new IllegalArgumentException("Invalid task, not in foreground");
10573                }
10574            }
10575            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10576                    "Locking fully");
10577            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10578                    ActivityManager.LOCK_TASK_MODE_PINNED :
10579                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10580                    "startLockTask", true);
10581        } finally {
10582            Binder.restoreCallingIdentity(ident);
10583        }
10584    }
10585
10586    @Override
10587    public void startLockTaskModeById(int taskId) {
10588        synchronized (this) {
10589            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10590            if (task != null) {
10591                startLockTaskModeLocked(task);
10592            }
10593        }
10594    }
10595
10596    @Override
10597    public void startLockTaskModeByToken(IBinder token) {
10598        synchronized (this) {
10599            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10600            if (r == null) {
10601                return;
10602            }
10603            final TaskRecord task = r.task;
10604            if (task != null) {
10605                startLockTaskModeLocked(task);
10606            }
10607        }
10608    }
10609
10610    @Override
10611    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10612        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10613        // This makes inner call to look as if it was initiated by system.
10614        long ident = Binder.clearCallingIdentity();
10615        try {
10616            synchronized (this) {
10617                startLockTaskModeById(taskId);
10618            }
10619        } finally {
10620            Binder.restoreCallingIdentity(ident);
10621        }
10622    }
10623
10624    @Override
10625    public void stopLockTaskMode() {
10626        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10627        if (lockTask == null) {
10628            // Our work here is done.
10629            return;
10630        }
10631
10632        final int callingUid = Binder.getCallingUid();
10633        final int lockTaskUid = lockTask.mLockTaskUid;
10634        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10635        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10636            // Done.
10637            return;
10638        } else {
10639            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10640            // It is possible lockTaskMode was started by the system process because
10641            // android:lockTaskMode is set to a locking value in the application manifest
10642            // instead of the app calling startLockTaskMode. In this case
10643            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10644            // {@link TaskRecord.effectiveUid} instead. Also caller with
10645            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10646            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10647                    && callingUid != lockTaskUid
10648                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10649                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10650                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10651            }
10652        }
10653        long ident = Binder.clearCallingIdentity();
10654        try {
10655            Log.d(TAG, "stopLockTaskMode");
10656            // Stop lock task
10657            synchronized (this) {
10658                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10659                        "stopLockTask", true);
10660            }
10661            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10662            if (tm != null) {
10663                tm.showInCallScreen(false);
10664            }
10665        } finally {
10666            Binder.restoreCallingIdentity(ident);
10667        }
10668    }
10669
10670    /**
10671     * This API should be called by SystemUI only when user perform certain action to dismiss
10672     * lock task mode. We should only dismiss pinned lock task mode in this case.
10673     */
10674    @Override
10675    public void stopSystemLockTaskMode() throws RemoteException {
10676        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10677            stopLockTaskMode();
10678        } else {
10679            mStackSupervisor.showLockTaskToast();
10680        }
10681    }
10682
10683    @Override
10684    public boolean isInLockTaskMode() {
10685        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10686    }
10687
10688    @Override
10689    public int getLockTaskModeState() {
10690        synchronized (this) {
10691            return mStackSupervisor.getLockTaskModeState();
10692        }
10693    }
10694
10695    @Override
10696    public void showLockTaskEscapeMessage(IBinder token) {
10697        synchronized (this) {
10698            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10699            if (r == null) {
10700                return;
10701            }
10702            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10703        }
10704    }
10705
10706    // =========================================================
10707    // CONTENT PROVIDERS
10708    // =========================================================
10709
10710    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10711        List<ProviderInfo> providers = null;
10712        try {
10713            providers = AppGlobals.getPackageManager()
10714                    .queryContentProviders(app.processName, app.uid,
10715                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10716                                    | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null)
10717                    .getList();
10718        } catch (RemoteException ex) {
10719        }
10720        if (DEBUG_MU) Slog.v(TAG_MU,
10721                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10722        int userId = app.userId;
10723        if (providers != null) {
10724            int N = providers.size();
10725            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10726            for (int i=0; i<N; i++) {
10727                // TODO: keep logic in sync with installEncryptionUnawareProviders
10728                ProviderInfo cpi =
10729                    (ProviderInfo)providers.get(i);
10730                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10731                        cpi.name, cpi.flags);
10732                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10733                    // This is a singleton provider, but a user besides the
10734                    // default user is asking to initialize a process it runs
10735                    // in...  well, no, it doesn't actually run in this process,
10736                    // it runs in the process of the default user.  Get rid of it.
10737                    providers.remove(i);
10738                    N--;
10739                    i--;
10740                    continue;
10741                }
10742
10743                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10744                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10745                if (cpr == null) {
10746                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10747                    mProviderMap.putProviderByClass(comp, cpr);
10748                }
10749                if (DEBUG_MU) Slog.v(TAG_MU,
10750                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10751                app.pubProviders.put(cpi.name, cpr);
10752                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10753                    // Don't add this if it is a platform component that is marked
10754                    // to run in multiple processes, because this is actually
10755                    // part of the framework so doesn't make sense to track as a
10756                    // separate apk in the process.
10757                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10758                            mProcessStats);
10759                }
10760                notifyPackageUse(cpi.applicationInfo.packageName,
10761                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10762            }
10763        }
10764        return providers;
10765    }
10766
10767    /**
10768     * Check if the calling UID has a possible chance at accessing the provider
10769     * at the given authority and user.
10770     */
10771    public String checkContentProviderAccess(String authority, int userId) {
10772        if (userId == UserHandle.USER_ALL) {
10773            mContext.enforceCallingOrSelfPermission(
10774                    Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
10775            userId = UserHandle.getCallingUserId();
10776        }
10777
10778        ProviderInfo cpi = null;
10779        try {
10780            cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
10781                    STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10782                            | PackageManager.MATCH_DISABLED_COMPONENTS
10783                            | PackageManager.MATCH_DIRECT_BOOT_AWARE
10784                            | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
10785                    userId);
10786        } catch (RemoteException ignored) {
10787        }
10788        if (cpi == null) {
10789            return "Failed to find provider " + authority + " for user " + userId;
10790        }
10791
10792        ProcessRecord r = null;
10793        synchronized (mPidsSelfLocked) {
10794            r = mPidsSelfLocked.get(Binder.getCallingPid());
10795        }
10796        if (r == null) {
10797            return "Failed to find PID " + Binder.getCallingPid();
10798        }
10799
10800        synchronized (this) {
10801            return checkContentProviderPermissionLocked(cpi, r, userId, true);
10802        }
10803    }
10804
10805    /**
10806     * Check if {@link ProcessRecord} has a possible chance at accessing the
10807     * given {@link ProviderInfo}. Final permission checking is always done
10808     * in {@link ContentProvider}.
10809     */
10810    private final String checkContentProviderPermissionLocked(
10811            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10812        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10813        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10814        boolean checkedGrants = false;
10815        if (checkUser) {
10816            // Looking for cross-user grants before enforcing the typical cross-users permissions
10817            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10818            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10819                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10820                    return null;
10821                }
10822                checkedGrants = true;
10823            }
10824            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10825                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10826            if (userId != tmpTargetUserId) {
10827                // When we actually went to determine the final targer user ID, this ended
10828                // up different than our initial check for the authority.  This is because
10829                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10830                // SELF.  So we need to re-check the grants again.
10831                checkedGrants = false;
10832            }
10833        }
10834        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10835                cpi.applicationInfo.uid, cpi.exported)
10836                == PackageManager.PERMISSION_GRANTED) {
10837            return null;
10838        }
10839        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10840                cpi.applicationInfo.uid, cpi.exported)
10841                == PackageManager.PERMISSION_GRANTED) {
10842            return null;
10843        }
10844
10845        PathPermission[] pps = cpi.pathPermissions;
10846        if (pps != null) {
10847            int i = pps.length;
10848            while (i > 0) {
10849                i--;
10850                PathPermission pp = pps[i];
10851                String pprperm = pp.getReadPermission();
10852                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10853                        cpi.applicationInfo.uid, cpi.exported)
10854                        == PackageManager.PERMISSION_GRANTED) {
10855                    return null;
10856                }
10857                String ppwperm = pp.getWritePermission();
10858                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10859                        cpi.applicationInfo.uid, cpi.exported)
10860                        == PackageManager.PERMISSION_GRANTED) {
10861                    return null;
10862                }
10863            }
10864        }
10865        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10866            return null;
10867        }
10868
10869        String msg;
10870        if (!cpi.exported) {
10871            msg = "Permission Denial: opening provider " + cpi.name
10872                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10873                    + ", uid=" + callingUid + ") that is not exported from uid "
10874                    + cpi.applicationInfo.uid;
10875        } else {
10876            msg = "Permission Denial: opening provider " + cpi.name
10877                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10878                    + ", uid=" + callingUid + ") requires "
10879                    + cpi.readPermission + " or " + cpi.writePermission;
10880        }
10881        Slog.w(TAG, msg);
10882        return msg;
10883    }
10884
10885    /**
10886     * Returns if the ContentProvider has granted a uri to callingUid
10887     */
10888    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10889        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10890        if (perms != null) {
10891            for (int i=perms.size()-1; i>=0; i--) {
10892                GrantUri grantUri = perms.keyAt(i);
10893                if (grantUri.sourceUserId == userId || !checkUser) {
10894                    if (matchesProvider(grantUri.uri, cpi)) {
10895                        return true;
10896                    }
10897                }
10898            }
10899        }
10900        return false;
10901    }
10902
10903    /**
10904     * Returns true if the uri authority is one of the authorities specified in the provider.
10905     */
10906    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10907        String uriAuth = uri.getAuthority();
10908        String cpiAuth = cpi.authority;
10909        if (cpiAuth.indexOf(';') == -1) {
10910            return cpiAuth.equals(uriAuth);
10911        }
10912        String[] cpiAuths = cpiAuth.split(";");
10913        int length = cpiAuths.length;
10914        for (int i = 0; i < length; i++) {
10915            if (cpiAuths[i].equals(uriAuth)) return true;
10916        }
10917        return false;
10918    }
10919
10920    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10921            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10922        if (r != null) {
10923            for (int i=0; i<r.conProviders.size(); i++) {
10924                ContentProviderConnection conn = r.conProviders.get(i);
10925                if (conn.provider == cpr) {
10926                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10927                            "Adding provider requested by "
10928                            + r.processName + " from process "
10929                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10930                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10931                    if (stable) {
10932                        conn.stableCount++;
10933                        conn.numStableIncs++;
10934                    } else {
10935                        conn.unstableCount++;
10936                        conn.numUnstableIncs++;
10937                    }
10938                    return conn;
10939                }
10940            }
10941            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10942            if (stable) {
10943                conn.stableCount = 1;
10944                conn.numStableIncs = 1;
10945            } else {
10946                conn.unstableCount = 1;
10947                conn.numUnstableIncs = 1;
10948            }
10949            cpr.connections.add(conn);
10950            r.conProviders.add(conn);
10951            startAssociationLocked(r.uid, r.processName, r.curProcState,
10952                    cpr.uid, cpr.name, cpr.info.processName);
10953            return conn;
10954        }
10955        cpr.addExternalProcessHandleLocked(externalProcessToken);
10956        return null;
10957    }
10958
10959    boolean decProviderCountLocked(ContentProviderConnection conn,
10960            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10961        if (conn != null) {
10962            cpr = conn.provider;
10963            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10964                    "Removing provider requested by "
10965                    + conn.client.processName + " from process "
10966                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10967                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10968            if (stable) {
10969                conn.stableCount--;
10970            } else {
10971                conn.unstableCount--;
10972            }
10973            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10974                cpr.connections.remove(conn);
10975                conn.client.conProviders.remove(conn);
10976                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10977                    // The client is more important than last activity -- note the time this
10978                    // is happening, so we keep the old provider process around a bit as last
10979                    // activity to avoid thrashing it.
10980                    if (cpr.proc != null) {
10981                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10982                    }
10983                }
10984                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10985                return true;
10986            }
10987            return false;
10988        }
10989        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10990        return false;
10991    }
10992
10993    private void checkTime(long startTime, String where) {
10994        long now = SystemClock.uptimeMillis();
10995        if ((now-startTime) > 50) {
10996            // If we are taking more than 50ms, log about it.
10997            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10998        }
10999    }
11000
11001    private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
11002            PROC_SPACE_TERM,
11003            PROC_SPACE_TERM|PROC_PARENS,
11004            PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
11005    };
11006
11007    private final long[] mProcessStateStatsLongs = new long[1];
11008
11009    boolean isProcessAliveLocked(ProcessRecord proc) {
11010        if (proc.procStatFile == null) {
11011            proc.procStatFile = "/proc/" + proc.pid + "/stat";
11012        }
11013        mProcessStateStatsLongs[0] = 0;
11014        if (!Process.readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
11015                mProcessStateStatsLongs, null)) {
11016            if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
11017            return false;
11018        }
11019        final long state = mProcessStateStatsLongs[0];
11020        if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
11021                + (char)state);
11022        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
11023    }
11024
11025    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
11026            String name, IBinder token, boolean stable, int userId) {
11027        ContentProviderRecord cpr;
11028        ContentProviderConnection conn = null;
11029        ProviderInfo cpi = null;
11030
11031        synchronized(this) {
11032            long startTime = SystemClock.uptimeMillis();
11033
11034            ProcessRecord r = null;
11035            if (caller != null) {
11036                r = getRecordForAppLocked(caller);
11037                if (r == null) {
11038                    throw new SecurityException(
11039                            "Unable to find app for caller " + caller
11040                          + " (pid=" + Binder.getCallingPid()
11041                          + ") when getting content provider " + name);
11042                }
11043            }
11044
11045            boolean checkCrossUser = true;
11046
11047            checkTime(startTime, "getContentProviderImpl: getProviderByName");
11048
11049            // First check if this content provider has been published...
11050            cpr = mProviderMap.getProviderByName(name, userId);
11051            // If that didn't work, check if it exists for user 0 and then
11052            // verify that it's a singleton provider before using it.
11053            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
11054                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
11055                if (cpr != null) {
11056                    cpi = cpr.info;
11057                    if (isSingleton(cpi.processName, cpi.applicationInfo,
11058                            cpi.name, cpi.flags)
11059                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
11060                        userId = UserHandle.USER_SYSTEM;
11061                        checkCrossUser = false;
11062                    } else {
11063                        cpr = null;
11064                        cpi = null;
11065                    }
11066                }
11067            }
11068
11069            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
11070            if (providerRunning) {
11071                cpi = cpr.info;
11072                String msg;
11073                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11074                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
11075                        != null) {
11076                    throw new SecurityException(msg);
11077                }
11078                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11079
11080                if (r != null && cpr.canRunHere(r)) {
11081                    // This provider has been published or is in the process
11082                    // of being published...  but it is also allowed to run
11083                    // in the caller's process, so don't make a connection
11084                    // and just let the caller instantiate its own instance.
11085                    ContentProviderHolder holder = cpr.newHolder(null);
11086                    // don't give caller the provider object, it needs
11087                    // to make its own.
11088                    holder.provider = null;
11089                    return holder;
11090                }
11091
11092                final long origId = Binder.clearCallingIdentity();
11093
11094                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
11095
11096                // In this case the provider instance already exists, so we can
11097                // return it right away.
11098                conn = incProviderCountLocked(r, cpr, token, stable);
11099                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
11100                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
11101                        // If this is a perceptible app accessing the provider,
11102                        // make sure to count it as being accessed and thus
11103                        // back up on the LRU list.  This is good because
11104                        // content providers are often expensive to start.
11105                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
11106                        updateLruProcessLocked(cpr.proc, false, null);
11107                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
11108                    }
11109                }
11110
11111                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
11112                final int verifiedAdj = cpr.proc.verifiedAdj;
11113                boolean success = updateOomAdjLocked(cpr.proc);
11114                // XXX things have changed so updateOomAdjLocked doesn't actually tell us
11115                // if the process has been successfully adjusted.  So to reduce races with
11116                // it, we will check whether the process still exists.  Note that this doesn't
11117                // completely get rid of races with LMK killing the process, but should make
11118                // them much smaller.
11119                if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
11120                    success = false;
11121                }
11122                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
11123                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
11124                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
11125                // NOTE: there is still a race here where a signal could be
11126                // pending on the process even though we managed to update its
11127                // adj level.  Not sure what to do about this, but at least
11128                // the race is now smaller.
11129                if (!success) {
11130                    // Uh oh...  it looks like the provider's process
11131                    // has been killed on us.  We need to wait for a new
11132                    // process to be started, and make sure its death
11133                    // doesn't kill our process.
11134                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
11135                            + " is crashing; detaching " + r);
11136                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
11137                    checkTime(startTime, "getContentProviderImpl: before appDied");
11138                    appDiedLocked(cpr.proc);
11139                    checkTime(startTime, "getContentProviderImpl: after appDied");
11140                    if (!lastRef) {
11141                        // This wasn't the last ref our process had on
11142                        // the provider...  we have now been killed, bail.
11143                        return null;
11144                    }
11145                    providerRunning = false;
11146                    conn = null;
11147                } else {
11148                    cpr.proc.verifiedAdj = cpr.proc.setAdj;
11149                }
11150
11151                Binder.restoreCallingIdentity(origId);
11152            }
11153
11154            if (!providerRunning) {
11155                try {
11156                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
11157                    cpi = AppGlobals.getPackageManager().
11158                        resolveContentProvider(name,
11159                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
11160                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
11161                } catch (RemoteException ex) {
11162                }
11163                if (cpi == null) {
11164                    return null;
11165                }
11166                // If the provider is a singleton AND
11167                // (it's a call within the same user || the provider is a
11168                // privileged app)
11169                // Then allow connecting to the singleton provider
11170                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11171                        cpi.name, cpi.flags)
11172                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
11173                if (singleton) {
11174                    userId = UserHandle.USER_SYSTEM;
11175                }
11176                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
11177                checkTime(startTime, "getContentProviderImpl: got app info for user");
11178
11179                String msg;
11180                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11181                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
11182                        != null) {
11183                    throw new SecurityException(msg);
11184                }
11185                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11186
11187                if (!mProcessesReady
11188                        && !cpi.processName.equals("system")) {
11189                    // If this content provider does not run in the system
11190                    // process, and the system is not yet ready to run other
11191                    // processes, then fail fast instead of hanging.
11192                    throw new IllegalArgumentException(
11193                            "Attempt to launch content provider before system ready");
11194                }
11195
11196                // Make sure that the user who owns this provider is running.  If not,
11197                // we don't want to allow it to run.
11198                if (!mUserController.isUserRunningLocked(userId, 0)) {
11199                    Slog.w(TAG, "Unable to launch app "
11200                            + cpi.applicationInfo.packageName + "/"
11201                            + cpi.applicationInfo.uid + " for provider "
11202                            + name + ": user " + userId + " is stopped");
11203                    return null;
11204                }
11205
11206                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11207                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
11208                cpr = mProviderMap.getProviderByClass(comp, userId);
11209                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
11210                final boolean firstClass = cpr == null;
11211                if (firstClass) {
11212                    final long ident = Binder.clearCallingIdentity();
11213
11214                    // If permissions need a review before any of the app components can run,
11215                    // we return no provider and launch a review activity if the calling app
11216                    // is in the foreground.
11217                    if (mPermissionReviewRequired) {
11218                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
11219                            return null;
11220                        }
11221                    }
11222
11223                    try {
11224                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
11225                        ApplicationInfo ai =
11226                            AppGlobals.getPackageManager().
11227                                getApplicationInfo(
11228                                        cpi.applicationInfo.packageName,
11229                                        STOCK_PM_FLAGS, userId);
11230                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
11231                        if (ai == null) {
11232                            Slog.w(TAG, "No package info for content provider "
11233                                    + cpi.name);
11234                            return null;
11235                        }
11236                        ai = getAppInfoForUser(ai, userId);
11237                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
11238                    } catch (RemoteException ex) {
11239                        // pm is in same process, this will never happen.
11240                    } finally {
11241                        Binder.restoreCallingIdentity(ident);
11242                    }
11243                }
11244
11245                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
11246
11247                if (r != null && cpr.canRunHere(r)) {
11248                    // If this is a multiprocess provider, then just return its
11249                    // info and allow the caller to instantiate it.  Only do
11250                    // this if the provider is the same user as the caller's
11251                    // process, or can run as root (so can be in any process).
11252                    return cpr.newHolder(null);
11253                }
11254
11255                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
11256                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
11257                            + cpr.info.name + " callers=" + Debug.getCallers(6));
11258
11259                // This is single process, and our app is now connecting to it.
11260                // See if we are already in the process of launching this
11261                // provider.
11262                final int N = mLaunchingProviders.size();
11263                int i;
11264                for (i = 0; i < N; i++) {
11265                    if (mLaunchingProviders.get(i) == cpr) {
11266                        break;
11267                    }
11268                }
11269
11270                // If the provider is not already being launched, then get it
11271                // started.
11272                if (i >= N) {
11273                    final long origId = Binder.clearCallingIdentity();
11274
11275                    try {
11276                        // Content provider is now in use, its package can't be stopped.
11277                        try {
11278                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
11279                            AppGlobals.getPackageManager().setPackageStoppedState(
11280                                    cpr.appInfo.packageName, false, userId);
11281                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
11282                        } catch (RemoteException e) {
11283                        } catch (IllegalArgumentException e) {
11284                            Slog.w(TAG, "Failed trying to unstop package "
11285                                    + cpr.appInfo.packageName + ": " + e);
11286                        }
11287
11288                        // Use existing process if already started
11289                        checkTime(startTime, "getContentProviderImpl: looking for process record");
11290                        ProcessRecord proc = getProcessRecordLocked(
11291                                cpi.processName, cpr.appInfo.uid, false);
11292                        if (proc != null && proc.thread != null && !proc.killed) {
11293                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
11294                                    "Installing in existing process " + proc);
11295                            if (!proc.pubProviders.containsKey(cpi.name)) {
11296                                checkTime(startTime, "getContentProviderImpl: scheduling install");
11297                                proc.pubProviders.put(cpi.name, cpr);
11298                                try {
11299                                    proc.thread.scheduleInstallProvider(cpi);
11300                                } catch (RemoteException e) {
11301                                }
11302                            }
11303                        } else {
11304                            checkTime(startTime, "getContentProviderImpl: before start process");
11305                            proc = startProcessLocked(cpi.processName,
11306                                    cpr.appInfo, false, 0, "content provider",
11307                                    new ComponentName(cpi.applicationInfo.packageName,
11308                                            cpi.name), false, false, false);
11309                            checkTime(startTime, "getContentProviderImpl: after start process");
11310                            if (proc == null) {
11311                                Slog.w(TAG, "Unable to launch app "
11312                                        + cpi.applicationInfo.packageName + "/"
11313                                        + cpi.applicationInfo.uid + " for provider "
11314                                        + name + ": process is bad");
11315                                return null;
11316                            }
11317                        }
11318                        cpr.launchingApp = proc;
11319                        mLaunchingProviders.add(cpr);
11320                    } finally {
11321                        Binder.restoreCallingIdentity(origId);
11322                    }
11323                }
11324
11325                checkTime(startTime, "getContentProviderImpl: updating data structures");
11326
11327                // Make sure the provider is published (the same provider class
11328                // may be published under multiple names).
11329                if (firstClass) {
11330                    mProviderMap.putProviderByClass(comp, cpr);
11331                }
11332
11333                mProviderMap.putProviderByName(name, cpr);
11334                conn = incProviderCountLocked(r, cpr, token, stable);
11335                if (conn != null) {
11336                    conn.waiting = true;
11337                }
11338            }
11339            checkTime(startTime, "getContentProviderImpl: done!");
11340        }
11341
11342        // Wait for the provider to be published...
11343        synchronized (cpr) {
11344            while (cpr.provider == null) {
11345                if (cpr.launchingApp == null) {
11346                    Slog.w(TAG, "Unable to launch app "
11347                            + cpi.applicationInfo.packageName + "/"
11348                            + cpi.applicationInfo.uid + " for provider "
11349                            + name + ": launching app became null");
11350                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
11351                            UserHandle.getUserId(cpi.applicationInfo.uid),
11352                            cpi.applicationInfo.packageName,
11353                            cpi.applicationInfo.uid, name);
11354                    return null;
11355                }
11356                try {
11357                    if (DEBUG_MU) Slog.v(TAG_MU,
11358                            "Waiting to start provider " + cpr
11359                            + " launchingApp=" + cpr.launchingApp);
11360                    if (conn != null) {
11361                        conn.waiting = true;
11362                    }
11363                    cpr.wait();
11364                } catch (InterruptedException ex) {
11365                } finally {
11366                    if (conn != null) {
11367                        conn.waiting = false;
11368                    }
11369                }
11370            }
11371        }
11372        return cpr != null ? cpr.newHolder(conn) : null;
11373    }
11374
11375    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11376            ProcessRecord r, final int userId) {
11377        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11378                cpi.packageName, userId)) {
11379
11380            final boolean callerForeground = r == null || r.setSchedGroup
11381                    != ProcessList.SCHED_GROUP_BACKGROUND;
11382
11383            // Show a permission review UI only for starting from a foreground app
11384            if (!callerForeground) {
11385                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11386                        + cpi.packageName + " requires a permissions review");
11387                return false;
11388            }
11389
11390            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11391            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11392                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11393            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11394
11395            if (DEBUG_PERMISSIONS_REVIEW) {
11396                Slog.i(TAG, "u" + userId + " Launching permission review "
11397                        + "for package " + cpi.packageName);
11398            }
11399
11400            final UserHandle userHandle = new UserHandle(userId);
11401            mHandler.post(new Runnable() {
11402                @Override
11403                public void run() {
11404                    mContext.startActivityAsUser(intent, userHandle);
11405                }
11406            });
11407
11408            return false;
11409        }
11410
11411        return true;
11412    }
11413
11414    PackageManagerInternal getPackageManagerInternalLocked() {
11415        if (mPackageManagerInt == null) {
11416            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11417        }
11418        return mPackageManagerInt;
11419    }
11420
11421    @Override
11422    public final ContentProviderHolder getContentProvider(
11423            IApplicationThread caller, String name, int userId, boolean stable) {
11424        enforceNotIsolatedCaller("getContentProvider");
11425        if (caller == null) {
11426            String msg = "null IApplicationThread when getting content provider "
11427                    + name;
11428            Slog.w(TAG, msg);
11429            throw new SecurityException(msg);
11430        }
11431        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11432        // with cross-user grant.
11433        return getContentProviderImpl(caller, name, null, stable, userId);
11434    }
11435
11436    public ContentProviderHolder getContentProviderExternal(
11437            String name, int userId, IBinder token) {
11438        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11439            "Do not have permission in call getContentProviderExternal()");
11440        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11441                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11442        return getContentProviderExternalUnchecked(name, token, userId);
11443    }
11444
11445    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11446            IBinder token, int userId) {
11447        return getContentProviderImpl(null, name, token, true, userId);
11448    }
11449
11450    /**
11451     * Drop a content provider from a ProcessRecord's bookkeeping
11452     */
11453    public void removeContentProvider(IBinder connection, boolean stable) {
11454        enforceNotIsolatedCaller("removeContentProvider");
11455        long ident = Binder.clearCallingIdentity();
11456        try {
11457            synchronized (this) {
11458                ContentProviderConnection conn;
11459                try {
11460                    conn = (ContentProviderConnection)connection;
11461                } catch (ClassCastException e) {
11462                    String msg ="removeContentProvider: " + connection
11463                            + " not a ContentProviderConnection";
11464                    Slog.w(TAG, msg);
11465                    throw new IllegalArgumentException(msg);
11466                }
11467                if (conn == null) {
11468                    throw new NullPointerException("connection is null");
11469                }
11470                if (decProviderCountLocked(conn, null, null, stable)) {
11471                    updateOomAdjLocked();
11472                }
11473            }
11474        } finally {
11475            Binder.restoreCallingIdentity(ident);
11476        }
11477    }
11478
11479    public void removeContentProviderExternal(String name, IBinder token) {
11480        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11481            "Do not have permission in call removeContentProviderExternal()");
11482        int userId = UserHandle.getCallingUserId();
11483        long ident = Binder.clearCallingIdentity();
11484        try {
11485            removeContentProviderExternalUnchecked(name, token, userId);
11486        } finally {
11487            Binder.restoreCallingIdentity(ident);
11488        }
11489    }
11490
11491    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11492        synchronized (this) {
11493            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11494            if(cpr == null) {
11495                //remove from mProvidersByClass
11496                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11497                return;
11498            }
11499
11500            //update content provider record entry info
11501            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11502            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11503            if (localCpr.hasExternalProcessHandles()) {
11504                if (localCpr.removeExternalProcessHandleLocked(token)) {
11505                    updateOomAdjLocked();
11506                } else {
11507                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11508                            + " with no external reference for token: "
11509                            + token + ".");
11510                }
11511            } else {
11512                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11513                        + " with no external references.");
11514            }
11515        }
11516    }
11517
11518    public final void publishContentProviders(IApplicationThread caller,
11519            List<ContentProviderHolder> providers) {
11520        if (providers == null) {
11521            return;
11522        }
11523
11524        enforceNotIsolatedCaller("publishContentProviders");
11525        synchronized (this) {
11526            final ProcessRecord r = getRecordForAppLocked(caller);
11527            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11528            if (r == null) {
11529                throw new SecurityException(
11530                        "Unable to find app for caller " + caller
11531                      + " (pid=" + Binder.getCallingPid()
11532                      + ") when publishing content providers");
11533            }
11534
11535            final long origId = Binder.clearCallingIdentity();
11536
11537            final int N = providers.size();
11538            for (int i = 0; i < N; i++) {
11539                ContentProviderHolder src = providers.get(i);
11540                if (src == null || src.info == null || src.provider == null) {
11541                    continue;
11542                }
11543                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11544                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11545                if (dst != null) {
11546                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11547                    mProviderMap.putProviderByClass(comp, dst);
11548                    String names[] = dst.info.authority.split(";");
11549                    for (int j = 0; j < names.length; j++) {
11550                        mProviderMap.putProviderByName(names[j], dst);
11551                    }
11552
11553                    int launchingCount = mLaunchingProviders.size();
11554                    int j;
11555                    boolean wasInLaunchingProviders = false;
11556                    for (j = 0; j < launchingCount; j++) {
11557                        if (mLaunchingProviders.get(j) == dst) {
11558                            mLaunchingProviders.remove(j);
11559                            wasInLaunchingProviders = true;
11560                            j--;
11561                            launchingCount--;
11562                        }
11563                    }
11564                    if (wasInLaunchingProviders) {
11565                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11566                    }
11567                    synchronized (dst) {
11568                        dst.provider = src.provider;
11569                        dst.proc = r;
11570                        dst.notifyAll();
11571                    }
11572                    updateOomAdjLocked(r);
11573                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11574                            src.info.authority);
11575                }
11576            }
11577
11578            Binder.restoreCallingIdentity(origId);
11579        }
11580    }
11581
11582    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11583        ContentProviderConnection conn;
11584        try {
11585            conn = (ContentProviderConnection)connection;
11586        } catch (ClassCastException e) {
11587            String msg ="refContentProvider: " + connection
11588                    + " not a ContentProviderConnection";
11589            Slog.w(TAG, msg);
11590            throw new IllegalArgumentException(msg);
11591        }
11592        if (conn == null) {
11593            throw new NullPointerException("connection is null");
11594        }
11595
11596        synchronized (this) {
11597            if (stable > 0) {
11598                conn.numStableIncs += stable;
11599            }
11600            stable = conn.stableCount + stable;
11601            if (stable < 0) {
11602                throw new IllegalStateException("stableCount < 0: " + stable);
11603            }
11604
11605            if (unstable > 0) {
11606                conn.numUnstableIncs += unstable;
11607            }
11608            unstable = conn.unstableCount + unstable;
11609            if (unstable < 0) {
11610                throw new IllegalStateException("unstableCount < 0: " + unstable);
11611            }
11612
11613            if ((stable+unstable) <= 0) {
11614                throw new IllegalStateException("ref counts can't go to zero here: stable="
11615                        + stable + " unstable=" + unstable);
11616            }
11617            conn.stableCount = stable;
11618            conn.unstableCount = unstable;
11619            return !conn.dead;
11620        }
11621    }
11622
11623    public void unstableProviderDied(IBinder connection) {
11624        ContentProviderConnection conn;
11625        try {
11626            conn = (ContentProviderConnection)connection;
11627        } catch (ClassCastException e) {
11628            String msg ="refContentProvider: " + connection
11629                    + " not a ContentProviderConnection";
11630            Slog.w(TAG, msg);
11631            throw new IllegalArgumentException(msg);
11632        }
11633        if (conn == null) {
11634            throw new NullPointerException("connection is null");
11635        }
11636
11637        // Safely retrieve the content provider associated with the connection.
11638        IContentProvider provider;
11639        synchronized (this) {
11640            provider = conn.provider.provider;
11641        }
11642
11643        if (provider == null) {
11644            // Um, yeah, we're way ahead of you.
11645            return;
11646        }
11647
11648        // Make sure the caller is being honest with us.
11649        if (provider.asBinder().pingBinder()) {
11650            // Er, no, still looks good to us.
11651            synchronized (this) {
11652                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11653                        + " says " + conn + " died, but we don't agree");
11654                return;
11655            }
11656        }
11657
11658        // Well look at that!  It's dead!
11659        synchronized (this) {
11660            if (conn.provider.provider != provider) {
11661                // But something changed...  good enough.
11662                return;
11663            }
11664
11665            ProcessRecord proc = conn.provider.proc;
11666            if (proc == null || proc.thread == null) {
11667                // Seems like the process is already cleaned up.
11668                return;
11669            }
11670
11671            // As far as we're concerned, this is just like receiving a
11672            // death notification...  just a bit prematurely.
11673            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11674                    + ") early provider death");
11675            final long ident = Binder.clearCallingIdentity();
11676            try {
11677                appDiedLocked(proc);
11678            } finally {
11679                Binder.restoreCallingIdentity(ident);
11680            }
11681        }
11682    }
11683
11684    @Override
11685    public void appNotRespondingViaProvider(IBinder connection) {
11686        enforceCallingPermission(
11687                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11688
11689        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11690        if (conn == null) {
11691            Slog.w(TAG, "ContentProviderConnection is null");
11692            return;
11693        }
11694
11695        final ProcessRecord host = conn.provider.proc;
11696        if (host == null) {
11697            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11698            return;
11699        }
11700
11701        mHandler.post(new Runnable() {
11702            @Override
11703            public void run() {
11704                mAppErrors.appNotResponding(host, null, null, false,
11705                        "ContentProvider not responding");
11706            }
11707        });
11708    }
11709
11710    public final void installSystemProviders() {
11711        List<ProviderInfo> providers;
11712        synchronized (this) {
11713            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11714            providers = generateApplicationProvidersLocked(app);
11715            if (providers != null) {
11716                for (int i=providers.size()-1; i>=0; i--) {
11717                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11718                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11719                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11720                                + ": not system .apk");
11721                        providers.remove(i);
11722                    }
11723                }
11724            }
11725        }
11726        if (providers != null) {
11727            mSystemThread.installSystemProviders(providers);
11728        }
11729
11730        mConstants.start(mContext.getContentResolver());
11731        mCoreSettingsObserver = new CoreSettingsObserver(this);
11732        mFontScaleSettingObserver = new FontScaleSettingObserver();
11733
11734        // Now that the settings provider is published we can consider sending
11735        // in a rescue party.
11736        RescueParty.onSettingsProviderPublished(mContext);
11737
11738        //mUsageStatsService.monitorPackages();
11739    }
11740
11741    private void startPersistentApps(int matchFlags) {
11742        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11743
11744        synchronized (this) {
11745            try {
11746                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11747                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11748                for (ApplicationInfo app : apps) {
11749                    if (!"android".equals(app.packageName)) {
11750                        addAppLocked(app, null, false, null /* ABI override */);
11751                    }
11752                }
11753            } catch (RemoteException ex) {
11754            }
11755        }
11756    }
11757
11758    /**
11759     * When a user is unlocked, we need to install encryption-unaware providers
11760     * belonging to any running apps.
11761     */
11762    private void installEncryptionUnawareProviders(int userId) {
11763        // We're only interested in providers that are encryption unaware, and
11764        // we don't care about uninstalled apps, since there's no way they're
11765        // running at this point.
11766        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11767
11768        synchronized (this) {
11769            final int NP = mProcessNames.getMap().size();
11770            for (int ip = 0; ip < NP; ip++) {
11771                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11772                final int NA = apps.size();
11773                for (int ia = 0; ia < NA; ia++) {
11774                    final ProcessRecord app = apps.valueAt(ia);
11775                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11776
11777                    final int NG = app.pkgList.size();
11778                    for (int ig = 0; ig < NG; ig++) {
11779                        try {
11780                            final String pkgName = app.pkgList.keyAt(ig);
11781                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11782                                    .getPackageInfo(pkgName, matchFlags, userId);
11783                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11784                                for (ProviderInfo pi : pkgInfo.providers) {
11785                                    // TODO: keep in sync with generateApplicationProvidersLocked
11786                                    final boolean processMatch = Objects.equals(pi.processName,
11787                                            app.processName) || pi.multiprocess;
11788                                    final boolean userMatch = isSingleton(pi.processName,
11789                                            pi.applicationInfo, pi.name, pi.flags)
11790                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
11791                                    if (processMatch && userMatch) {
11792                                        Log.v(TAG, "Installing " + pi);
11793                                        app.thread.scheduleInstallProvider(pi);
11794                                    } else {
11795                                        Log.v(TAG, "Skipping " + pi);
11796                                    }
11797                                }
11798                            }
11799                        } catch (RemoteException ignored) {
11800                        }
11801                    }
11802                }
11803            }
11804        }
11805    }
11806
11807    /**
11808     * Allows apps to retrieve the MIME type of a URI.
11809     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11810     * users, then it does not need permission to access the ContentProvider.
11811     * Either, it needs cross-user uri grants.
11812     *
11813     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11814     *
11815     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11816     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11817     */
11818    public String getProviderMimeType(Uri uri, int userId) {
11819        enforceNotIsolatedCaller("getProviderMimeType");
11820        final String name = uri.getAuthority();
11821        int callingUid = Binder.getCallingUid();
11822        int callingPid = Binder.getCallingPid();
11823        long ident = 0;
11824        boolean clearedIdentity = false;
11825        synchronized (this) {
11826            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11827        }
11828        if (canClearIdentity(callingPid, callingUid, userId)) {
11829            clearedIdentity = true;
11830            ident = Binder.clearCallingIdentity();
11831        }
11832        ContentProviderHolder holder = null;
11833        try {
11834            holder = getContentProviderExternalUnchecked(name, null, userId);
11835            if (holder != null) {
11836                return holder.provider.getType(uri);
11837            }
11838        } catch (RemoteException e) {
11839            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11840            return null;
11841        } catch (Exception e) {
11842            Log.w(TAG, "Exception while determining type of " + uri, e);
11843            return null;
11844        } finally {
11845            // We need to clear the identity to call removeContentProviderExternalUnchecked
11846            if (!clearedIdentity) {
11847                ident = Binder.clearCallingIdentity();
11848            }
11849            try {
11850                if (holder != null) {
11851                    removeContentProviderExternalUnchecked(name, null, userId);
11852                }
11853            } finally {
11854                Binder.restoreCallingIdentity(ident);
11855            }
11856        }
11857
11858        return null;
11859    }
11860
11861    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11862        if (UserHandle.getUserId(callingUid) == userId) {
11863            return true;
11864        }
11865        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11866                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11867                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11868                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11869                return true;
11870        }
11871        return false;
11872    }
11873
11874    // =========================================================
11875    // GLOBAL MANAGEMENT
11876    // =========================================================
11877
11878    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11879            boolean isolated, int isolatedUid) {
11880        String proc = customProcess != null ? customProcess : info.processName;
11881        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11882        final int userId = UserHandle.getUserId(info.uid);
11883        int uid = info.uid;
11884        if (isolated) {
11885            if (isolatedUid == 0) {
11886                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11887                while (true) {
11888                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11889                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11890                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11891                    }
11892                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11893                    mNextIsolatedProcessUid++;
11894                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11895                        // No process for this uid, use it.
11896                        break;
11897                    }
11898                    stepsLeft--;
11899                    if (stepsLeft <= 0) {
11900                        return null;
11901                    }
11902                }
11903            } else {
11904                // Special case for startIsolatedProcess (internal only), where
11905                // the uid of the isolated process is specified by the caller.
11906                uid = isolatedUid;
11907            }
11908
11909            // Register the isolated UID with this application so BatteryStats knows to
11910            // attribute resource usage to the application.
11911            //
11912            // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
11913            // about the process state of the isolated UID *before* it is registered with the
11914            // owning application.
11915            mBatteryStatsService.addIsolatedUid(uid, info.uid);
11916        }
11917        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11918        if (!mBooted && !mBooting
11919                && userId == UserHandle.USER_SYSTEM
11920                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11921            r.persistent = true;
11922            r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11923        }
11924        addProcessNameLocked(r);
11925        return r;
11926    }
11927
11928    private boolean uidOnBackgroundWhitelist(final int uid) {
11929        final int N = mBackgroundUidWhitelist.length;
11930        for (int i = 0; i < N; i++) {
11931            if (uid == mBackgroundUidWhitelist[i]) {
11932                return true;
11933            }
11934        }
11935        return false;
11936    }
11937
11938    final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
11939            String abiOverride) {
11940        ProcessRecord app;
11941        if (!isolated) {
11942            app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
11943                    info.uid, true);
11944        } else {
11945            app = null;
11946        }
11947
11948        if (app == null) {
11949            app = newProcessRecordLocked(info, customProcess, isolated, 0);
11950            updateLruProcessLocked(app, false, null);
11951            updateOomAdjLocked();
11952        }
11953
11954        // This package really, really can not be stopped.
11955        try {
11956            AppGlobals.getPackageManager().setPackageStoppedState(
11957                    info.packageName, false, UserHandle.getUserId(app.uid));
11958        } catch (RemoteException e) {
11959        } catch (IllegalArgumentException e) {
11960            Slog.w(TAG, "Failed trying to unstop package "
11961                    + info.packageName + ": " + e);
11962        }
11963
11964        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11965            app.persistent = true;
11966            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11967        }
11968        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11969            mPersistentStartingProcesses.add(app);
11970            startProcessLocked(app, "added application",
11971                    customProcess != null ? customProcess : app.processName, abiOverride,
11972                    null /* entryPoint */, null /* entryPointArgs */);
11973        }
11974
11975        return app;
11976    }
11977
11978    public void unhandledBack() {
11979        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11980                "unhandledBack()");
11981
11982        synchronized(this) {
11983            final long origId = Binder.clearCallingIdentity();
11984            try {
11985                getFocusedStack().unhandledBackLocked();
11986            } finally {
11987                Binder.restoreCallingIdentity(origId);
11988            }
11989        }
11990    }
11991
11992    public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
11993        enforceNotIsolatedCaller("openContentUri");
11994        final int userId = UserHandle.getCallingUserId();
11995        final Uri uri = Uri.parse(uriString);
11996        String name = uri.getAuthority();
11997        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11998        ParcelFileDescriptor pfd = null;
11999        if (cph != null) {
12000            // We record the binder invoker's uid in thread-local storage before
12001            // going to the content provider to open the file.  Later, in the code
12002            // that handles all permissions checks, we look for this uid and use
12003            // that rather than the Activity Manager's own uid.  The effect is that
12004            // we do the check against the caller's permissions even though it looks
12005            // to the content provider like the Activity Manager itself is making
12006            // the request.
12007            Binder token = new Binder();
12008            sCallerIdentity.set(new Identity(
12009                    token, Binder.getCallingPid(), Binder.getCallingUid()));
12010            try {
12011                pfd = cph.provider.openFile(null, uri, "r", null, token);
12012            } catch (FileNotFoundException e) {
12013                // do nothing; pfd will be returned null
12014            } finally {
12015                // Ensure that whatever happens, we clean up the identity state
12016                sCallerIdentity.remove();
12017                // Ensure we're done with the provider.
12018                removeContentProviderExternalUnchecked(name, null, userId);
12019            }
12020        } else {
12021            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
12022        }
12023        return pfd;
12024    }
12025
12026    // Actually is sleeping or shutting down or whatever else in the future
12027    // is an inactive state.
12028    boolean isSleepingOrShuttingDownLocked() {
12029        return isSleepingLocked() || mShuttingDown;
12030    }
12031
12032    boolean isShuttingDownLocked() {
12033        return mShuttingDown;
12034    }
12035
12036    boolean isSleepingLocked() {
12037        return mSleeping;
12038    }
12039
12040    void onWakefulnessChanged(int wakefulness) {
12041        synchronized(this) {
12042            mWakefulness = wakefulness;
12043            updateSleepIfNeededLocked();
12044        }
12045    }
12046
12047    void finishRunningVoiceLocked() {
12048        if (mRunningVoice != null) {
12049            mRunningVoice = null;
12050            mVoiceWakeLock.release();
12051            updateSleepIfNeededLocked();
12052        }
12053    }
12054
12055    void startTimeTrackingFocusedActivityLocked() {
12056        final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
12057        if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
12058            mCurAppTimeTracker.start(resumedActivity.packageName);
12059        }
12060    }
12061
12062    void updateSleepIfNeededLocked() {
12063        if (mSleeping && !shouldSleepLocked()) {
12064            mSleeping = false;
12065            startTimeTrackingFocusedActivityLocked();
12066            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
12067            mStackSupervisor.comeOutOfSleepIfNeededLocked();
12068            sendNotifyVrManagerOfSleepState(false);
12069            updateOomAdjLocked();
12070        } else if (!mSleeping && shouldSleepLocked()) {
12071            mSleeping = true;
12072            if (mCurAppTimeTracker != null) {
12073                mCurAppTimeTracker.stop();
12074            }
12075            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
12076            mStackSupervisor.goingToSleepLocked();
12077            sendNotifyVrManagerOfSleepState(true);
12078            updateOomAdjLocked();
12079
12080            // Initialize the wake times of all processes.
12081            checkExcessivePowerUsageLocked(false);
12082            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
12083            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
12084            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
12085        }
12086    }
12087
12088    private boolean shouldSleepLocked() {
12089        // Resume applications while running a voice interactor.
12090        if (mRunningVoice != null) {
12091            return false;
12092        }
12093
12094        // TODO: Transform the lock screen state into a sleep token instead.
12095        switch (mWakefulness) {
12096            case PowerManagerInternal.WAKEFULNESS_AWAKE:
12097            case PowerManagerInternal.WAKEFULNESS_DREAMING:
12098            case PowerManagerInternal.WAKEFULNESS_DOZING:
12099                // Pause applications whenever the lock screen is shown or any sleep
12100                // tokens have been acquired.
12101                return mKeyguardController.isKeyguardShowing() || !mSleepTokens.isEmpty();
12102            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
12103            default:
12104                // If we're asleep then pause applications unconditionally.
12105                return true;
12106        }
12107    }
12108
12109    /** Pokes the task persister. */
12110    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
12111        mRecentTasks.notifyTaskPersisterLocked(task, flush);
12112    }
12113
12114    /** Notifies all listeners when the pinned stack animation starts. */
12115    @Override
12116    public void notifyPinnedStackAnimationStarted() {
12117        mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
12118    }
12119
12120    /** Notifies all listeners when the pinned stack animation ends. */
12121    @Override
12122    public void notifyPinnedStackAnimationEnded() {
12123        mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
12124    }
12125
12126    @Override
12127    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
12128        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
12129    }
12130
12131    @Override
12132    public boolean shutdown(int timeout) {
12133        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
12134                != PackageManager.PERMISSION_GRANTED) {
12135            throw new SecurityException("Requires permission "
12136                    + android.Manifest.permission.SHUTDOWN);
12137        }
12138
12139        boolean timedout = false;
12140
12141        synchronized(this) {
12142            mShuttingDown = true;
12143            updateEventDispatchingLocked();
12144            timedout = mStackSupervisor.shutdownLocked(timeout);
12145        }
12146
12147        mAppOpsService.shutdown();
12148        if (mUsageStatsService != null) {
12149            mUsageStatsService.prepareShutdown();
12150        }
12151        mBatteryStatsService.shutdown();
12152        synchronized (this) {
12153            mProcessStats.shutdownLocked();
12154            notifyTaskPersisterLocked(null, true);
12155        }
12156
12157        return timedout;
12158    }
12159
12160    public final void activitySlept(IBinder token) {
12161        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
12162
12163        final long origId = Binder.clearCallingIdentity();
12164
12165        synchronized (this) {
12166            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12167            if (r != null) {
12168                mStackSupervisor.activitySleptLocked(r);
12169            }
12170        }
12171
12172        Binder.restoreCallingIdentity(origId);
12173    }
12174
12175    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
12176        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
12177        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
12178        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
12179            boolean wasRunningVoice = mRunningVoice != null;
12180            mRunningVoice = session;
12181            if (!wasRunningVoice) {
12182                mVoiceWakeLock.acquire();
12183                updateSleepIfNeededLocked();
12184            }
12185        }
12186    }
12187
12188    private void updateEventDispatchingLocked() {
12189        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
12190    }
12191
12192    @Override
12193    public void setLockScreenShown(boolean showing) {
12194        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
12195                != PackageManager.PERMISSION_GRANTED) {
12196            throw new SecurityException("Requires permission "
12197                    + android.Manifest.permission.DEVICE_POWER);
12198        }
12199
12200        synchronized(this) {
12201            long ident = Binder.clearCallingIdentity();
12202            try {
12203                mKeyguardController.setKeyguardShown(showing);
12204            } finally {
12205                Binder.restoreCallingIdentity(ident);
12206            }
12207        }
12208    }
12209
12210    @Override
12211    public void notifyLockedProfile(@UserIdInt int userId) {
12212        try {
12213            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
12214                throw new SecurityException("Only privileged app can call notifyLockedProfile");
12215            }
12216        } catch (RemoteException ex) {
12217            throw new SecurityException("Fail to check is caller a privileged app", ex);
12218        }
12219
12220        synchronized (this) {
12221            final long ident = Binder.clearCallingIdentity();
12222            try {
12223                if (mUserController.shouldConfirmCredentials(userId)) {
12224                    if (mKeyguardController.isKeyguardLocked()) {
12225                        // Showing launcher to avoid user entering credential twice.
12226                        final int currentUserId = mUserController.getCurrentUserIdLocked();
12227                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
12228                    }
12229                    mStackSupervisor.lockAllProfileTasks(userId);
12230                }
12231            } finally {
12232                Binder.restoreCallingIdentity(ident);
12233            }
12234        }
12235    }
12236
12237    @Override
12238    public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
12239        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
12240        synchronized (this) {
12241            final long ident = Binder.clearCallingIdentity();
12242            try {
12243                mActivityStarter.startConfirmCredentialIntent(intent, options);
12244            } finally {
12245                Binder.restoreCallingIdentity(ident);
12246            }
12247        }
12248    }
12249
12250    @Override
12251    public void stopAppSwitches() {
12252        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12253                != PackageManager.PERMISSION_GRANTED) {
12254            throw new SecurityException("viewquires permission "
12255                    + android.Manifest.permission.STOP_APP_SWITCHES);
12256        }
12257
12258        synchronized(this) {
12259            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
12260                    + APP_SWITCH_DELAY_TIME;
12261            mDidAppSwitch = false;
12262            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12263            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12264            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
12265        }
12266    }
12267
12268    public void resumeAppSwitches() {
12269        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12270                != PackageManager.PERMISSION_GRANTED) {
12271            throw new SecurityException("Requires permission "
12272                    + android.Manifest.permission.STOP_APP_SWITCHES);
12273        }
12274
12275        synchronized(this) {
12276            // Note that we don't execute any pending app switches... we will
12277            // let those wait until either the timeout, or the next start
12278            // activity request.
12279            mAppSwitchesAllowedTime = 0;
12280        }
12281    }
12282
12283    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
12284            int callingPid, int callingUid, String name) {
12285        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
12286            return true;
12287        }
12288
12289        int perm = checkComponentPermission(
12290                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
12291                sourceUid, -1, true);
12292        if (perm == PackageManager.PERMISSION_GRANTED) {
12293            return true;
12294        }
12295
12296        // If the actual IPC caller is different from the logical source, then
12297        // also see if they are allowed to control app switches.
12298        if (callingUid != -1 && callingUid != sourceUid) {
12299            perm = checkComponentPermission(
12300                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
12301                    callingUid, -1, true);
12302            if (perm == PackageManager.PERMISSION_GRANTED) {
12303                return true;
12304            }
12305        }
12306
12307        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
12308        return false;
12309    }
12310
12311    public void setDebugApp(String packageName, boolean waitForDebugger,
12312            boolean persistent) {
12313        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
12314                "setDebugApp()");
12315
12316        long ident = Binder.clearCallingIdentity();
12317        try {
12318            // Note that this is not really thread safe if there are multiple
12319            // callers into it at the same time, but that's not a situation we
12320            // care about.
12321            if (persistent) {
12322                final ContentResolver resolver = mContext.getContentResolver();
12323                Settings.Global.putString(
12324                    resolver, Settings.Global.DEBUG_APP,
12325                    packageName);
12326                Settings.Global.putInt(
12327                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
12328                    waitForDebugger ? 1 : 0);
12329            }
12330
12331            synchronized (this) {
12332                if (!persistent) {
12333                    mOrigDebugApp = mDebugApp;
12334                    mOrigWaitForDebugger = mWaitForDebugger;
12335                }
12336                mDebugApp = packageName;
12337                mWaitForDebugger = waitForDebugger;
12338                mDebugTransient = !persistent;
12339                if (packageName != null) {
12340                    forceStopPackageLocked(packageName, -1, false, false, true, true,
12341                            false, UserHandle.USER_ALL, "set debug app");
12342                }
12343            }
12344        } finally {
12345            Binder.restoreCallingIdentity(ident);
12346        }
12347    }
12348
12349    void setTrackAllocationApp(ApplicationInfo app, String processName) {
12350        synchronized (this) {
12351            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12352            if (!isDebuggable) {
12353                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12354                    throw new SecurityException("Process not debuggable: " + app.packageName);
12355                }
12356            }
12357
12358            mTrackAllocationApp = processName;
12359        }
12360    }
12361
12362    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
12363        synchronized (this) {
12364            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12365            if (!isDebuggable) {
12366                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12367                    throw new SecurityException("Process not debuggable: " + app.packageName);
12368                }
12369            }
12370            mProfileApp = processName;
12371            mProfileFile = profilerInfo.profileFile;
12372            if (mProfileFd != null) {
12373                try {
12374                    mProfileFd.close();
12375                } catch (IOException e) {
12376                }
12377                mProfileFd = null;
12378            }
12379            mProfileFd = profilerInfo.profileFd;
12380            mSamplingInterval = profilerInfo.samplingInterval;
12381            mAutoStopProfiler = profilerInfo.autoStopProfiler;
12382            mStreamingOutput = profilerInfo.streamingOutput;
12383            mProfileType = 0;
12384        }
12385    }
12386
12387    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12388        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12389        if (!isDebuggable) {
12390            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12391                throw new SecurityException("Process not debuggable: " + app.packageName);
12392            }
12393        }
12394        mNativeDebuggingApp = processName;
12395    }
12396
12397    @Override
12398    public void setAlwaysFinish(boolean enabled) {
12399        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12400                "setAlwaysFinish()");
12401
12402        long ident = Binder.clearCallingIdentity();
12403        try {
12404            Settings.Global.putInt(
12405                    mContext.getContentResolver(),
12406                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12407
12408            synchronized (this) {
12409                mAlwaysFinishActivities = enabled;
12410            }
12411        } finally {
12412            Binder.restoreCallingIdentity(ident);
12413        }
12414    }
12415
12416    @Override
12417    public void setActivityController(IActivityController controller, boolean imAMonkey) {
12418        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12419                "setActivityController()");
12420        synchronized (this) {
12421            mController = controller;
12422            mControllerIsAMonkey = imAMonkey;
12423            Watchdog.getInstance().setActivityController(controller);
12424        }
12425    }
12426
12427    @Override
12428    public void setUserIsMonkey(boolean userIsMonkey) {
12429        synchronized (this) {
12430            synchronized (mPidsSelfLocked) {
12431                final int callingPid = Binder.getCallingPid();
12432                ProcessRecord proc = mPidsSelfLocked.get(callingPid);
12433                if (proc == null) {
12434                    throw new SecurityException("Unknown process: " + callingPid);
12435                }
12436                if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
12437                    throw new SecurityException("Only an instrumentation process "
12438                            + "with a UiAutomation can call setUserIsMonkey");
12439                }
12440            }
12441            mUserIsMonkey = userIsMonkey;
12442        }
12443    }
12444
12445    @Override
12446    public boolean isUserAMonkey() {
12447        synchronized (this) {
12448            // If there is a controller also implies the user is a monkey.
12449            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12450        }
12451    }
12452
12453    /**
12454     * @deprecated This method is only used by a few internal components and it will soon be
12455     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12456     * No new code should be calling it.
12457     */
12458    @Deprecated
12459    public void requestBugReport(int bugreportType) {
12460        String extraOptions = null;
12461        switch (bugreportType) {
12462            case ActivityManager.BUGREPORT_OPTION_FULL:
12463                // Default options.
12464                break;
12465            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12466                extraOptions = "bugreportplus";
12467                break;
12468            case ActivityManager.BUGREPORT_OPTION_REMOTE:
12469                extraOptions = "bugreportremote";
12470                break;
12471            case ActivityManager.BUGREPORT_OPTION_WEAR:
12472                extraOptions = "bugreportwear";
12473                break;
12474            case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
12475                extraOptions = "bugreporttelephony";
12476                break;
12477            default:
12478                throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12479                        + bugreportType);
12480        }
12481        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12482        if (extraOptions != null) {
12483            SystemProperties.set("dumpstate.options", extraOptions);
12484        }
12485        SystemProperties.set("ctl.start", "bugreport");
12486    }
12487
12488    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12489        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12490    }
12491
12492    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12493        if (r != null && (r.instr != null || r.usingWrapper)) {
12494            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12495        }
12496        return KEY_DISPATCHING_TIMEOUT;
12497    }
12498
12499    @Override
12500    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12501        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12502                != PackageManager.PERMISSION_GRANTED) {
12503            throw new SecurityException("Requires permission "
12504                    + android.Manifest.permission.FILTER_EVENTS);
12505        }
12506        ProcessRecord proc;
12507        long timeout;
12508        synchronized (this) {
12509            synchronized (mPidsSelfLocked) {
12510                proc = mPidsSelfLocked.get(pid);
12511            }
12512            timeout = getInputDispatchingTimeoutLocked(proc);
12513        }
12514
12515        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12516            return -1;
12517        }
12518
12519        return timeout;
12520    }
12521
12522    /**
12523     * Handle input dispatching timeouts.
12524     * Returns whether input dispatching should be aborted or not.
12525     */
12526    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12527            final ActivityRecord activity, final ActivityRecord parent,
12528            final boolean aboveSystem, String reason) {
12529        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12530                != PackageManager.PERMISSION_GRANTED) {
12531            throw new SecurityException("Requires permission "
12532                    + android.Manifest.permission.FILTER_EVENTS);
12533        }
12534
12535        final String annotation;
12536        if (reason == null) {
12537            annotation = "Input dispatching timed out";
12538        } else {
12539            annotation = "Input dispatching timed out (" + reason + ")";
12540        }
12541
12542        if (proc != null) {
12543            synchronized (this) {
12544                if (proc.debugging) {
12545                    return false;
12546                }
12547
12548                if (mDidDexOpt) {
12549                    // Give more time since we were dexopting.
12550                    mDidDexOpt = false;
12551                    return false;
12552                }
12553
12554                if (proc.instr != null) {
12555                    Bundle info = new Bundle();
12556                    info.putString("shortMsg", "keyDispatchingTimedOut");
12557                    info.putString("longMsg", annotation);
12558                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12559                    return true;
12560                }
12561            }
12562            mHandler.post(new Runnable() {
12563                @Override
12564                public void run() {
12565                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12566                }
12567            });
12568        }
12569
12570        return true;
12571    }
12572
12573    @Override
12574    public Bundle getAssistContextExtras(int requestType) {
12575        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12576                null, null, true /* focused */, true /* newSessionId */,
12577                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12578        if (pae == null) {
12579            return null;
12580        }
12581        synchronized (pae) {
12582            while (!pae.haveResult) {
12583                try {
12584                    pae.wait();
12585                } catch (InterruptedException e) {
12586                }
12587            }
12588        }
12589        synchronized (this) {
12590            buildAssistBundleLocked(pae, pae.result);
12591            mPendingAssistExtras.remove(pae);
12592            mUiHandler.removeCallbacks(pae);
12593        }
12594        return pae.extras;
12595    }
12596
12597    @Override
12598    public boolean isAssistDataAllowedOnCurrentActivity() {
12599        int userId;
12600        synchronized (this) {
12601            final ActivityStack focusedStack = getFocusedStack();
12602            if (focusedStack == null || focusedStack.isAssistantStack()) {
12603                return false;
12604            }
12605
12606            final ActivityRecord activity = focusedStack.topActivity();
12607            if (activity == null) {
12608                return false;
12609            }
12610            userId = activity.userId;
12611        }
12612        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12613                Context.DEVICE_POLICY_SERVICE);
12614        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12615    }
12616
12617    @Override
12618    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12619        long ident = Binder.clearCallingIdentity();
12620        try {
12621            synchronized (this) {
12622                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12623                ActivityRecord top = getFocusedStack().topActivity();
12624                if (top != caller) {
12625                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12626                            + " is not current top " + top);
12627                    return false;
12628                }
12629                if (!top.nowVisible) {
12630                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12631                            + " is not visible");
12632                    return false;
12633                }
12634            }
12635            return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
12636                    token);
12637        } finally {
12638            Binder.restoreCallingIdentity(ident);
12639        }
12640    }
12641
12642    @Override
12643    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12644            Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
12645        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12646                activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
12647                PENDING_ASSIST_EXTRAS_LONG_TIMEOUT) != null;
12648    }
12649
12650    @Override
12651    public boolean requestAutoFillData(IResultReceiver receiver, Bundle receiverExtras,
12652            IBinder activityToken) {
12653        // NOTE: we could always use ActivityManager.ASSIST_CONTEXT_FULL and let ActivityThread
12654        // rely on the flags to decide whether the handleRequestAssistContextExtras() is for
12655        // auto-fill, but it's safer to explicitly use new AutoFill types, in case the Assist
12656        // requests use flags in the future as well (since their flags value might collide with the
12657        // auto-fill flag values).
12658        return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTO_FILL, null, null,
12659                receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
12660                null, PENDING_AUTO_FILL_ASSIST_STRUCTURE_TIMEOUT) != null;
12661    }
12662
12663    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12664            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12665            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12666        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12667                "enqueueAssistContext()");
12668
12669        synchronized (this) {
12670            ActivityRecord activity = getFocusedStack().topActivity();
12671            if (activity == null) {
12672                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12673                return null;
12674            }
12675            if (activity.app == null || activity.app.thread == null) {
12676                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12677                return null;
12678            }
12679            if (focused) {
12680                if (activityToken != null) {
12681                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12682                    if (activity != caller) {
12683                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12684                                + " is not current top " + activity);
12685                        return null;
12686                    }
12687                }
12688            } else {
12689                activity = ActivityRecord.forTokenLocked(activityToken);
12690                if (activity == null) {
12691                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12692                            + " couldn't be found");
12693                    return null;
12694                }
12695            }
12696
12697            PendingAssistExtras pae;
12698            Bundle extras = new Bundle();
12699            if (args != null) {
12700                extras.putAll(args);
12701            }
12702            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12703            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12704
12705            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12706                    userHandle);
12707
12708            // Increment the sessionId if necessary
12709            if (newSessionId) {
12710                mViSessionId++;
12711            }
12712            try {
12713                activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
12714                        mViSessionId);
12715                mPendingAssistExtras.add(pae);
12716                mUiHandler.postDelayed(pae, timeout);
12717            } catch (RemoteException e) {
12718                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12719                return null;
12720            }
12721            return pae;
12722        }
12723    }
12724
12725    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12726        IResultReceiver receiver;
12727        synchronized (this) {
12728            mPendingAssistExtras.remove(pae);
12729            receiver = pae.receiver;
12730        }
12731        if (receiver != null) {
12732            // Caller wants result sent back to them.
12733            Bundle sendBundle = new Bundle();
12734            // At least return the receiver extras
12735            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12736                    pae.receiverExtras);
12737            try {
12738                pae.receiver.send(0, sendBundle);
12739            } catch (RemoteException e) {
12740            }
12741        }
12742    }
12743
12744    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12745        if (result != null) {
12746            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12747        }
12748        if (pae.hint != null) {
12749            pae.extras.putBoolean(pae.hint, true);
12750        }
12751    }
12752
12753    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12754            AssistContent content, Uri referrer) {
12755        PendingAssistExtras pae = (PendingAssistExtras)token;
12756        synchronized (pae) {
12757            pae.result = extras;
12758            pae.structure = structure;
12759            pae.content = content;
12760            if (referrer != null) {
12761                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12762            }
12763            pae.haveResult = true;
12764            pae.notifyAll();
12765            if (pae.intent == null && pae.receiver == null) {
12766                // Caller is just waiting for the result.
12767                return;
12768            }
12769        }
12770
12771        // We are now ready to launch the assist activity.
12772        IResultReceiver sendReceiver = null;
12773        Bundle sendBundle = null;
12774        synchronized (this) {
12775            buildAssistBundleLocked(pae, extras);
12776            boolean exists = mPendingAssistExtras.remove(pae);
12777            mUiHandler.removeCallbacks(pae);
12778            if (!exists) {
12779                // Timed out.
12780                return;
12781            }
12782            if ((sendReceiver=pae.receiver) != null) {
12783                // Caller wants result sent back to them.
12784                sendBundle = new Bundle();
12785                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12786                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12787                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12788                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12789                        pae.receiverExtras);
12790            }
12791        }
12792        if (sendReceiver != null) {
12793            try {
12794                sendReceiver.send(0, sendBundle);
12795            } catch (RemoteException e) {
12796            }
12797            return;
12798        }
12799
12800        long ident = Binder.clearCallingIdentity();
12801        try {
12802            pae.intent.replaceExtras(pae.extras);
12803            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12804                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12805                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12806            closeSystemDialogs("assist");
12807            try {
12808                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12809            } catch (ActivityNotFoundException e) {
12810                Slog.w(TAG, "No activity to handle assist action.", e);
12811            }
12812        } finally {
12813            Binder.restoreCallingIdentity(ident);
12814        }
12815    }
12816
12817    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12818            Bundle args) {
12819        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12820                true /* focused */, true /* newSessionId */, userHandle, args,
12821                PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12822    }
12823
12824    public void registerProcessObserver(IProcessObserver observer) {
12825        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12826                "registerProcessObserver()");
12827        synchronized (this) {
12828            mProcessObservers.register(observer);
12829        }
12830    }
12831
12832    @Override
12833    public void unregisterProcessObserver(IProcessObserver observer) {
12834        synchronized (this) {
12835            mProcessObservers.unregister(observer);
12836        }
12837    }
12838
12839    @Override
12840    public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
12841            String callingPackage) {
12842        if (!hasUsageStatsPermission(callingPackage)) {
12843            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
12844                    "registerUidObserver");
12845        }
12846        synchronized (this) {
12847            mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
12848                    callingPackage, which, cutpoint));
12849        }
12850    }
12851
12852    @Override
12853    public void unregisterUidObserver(IUidObserver observer) {
12854        synchronized (this) {
12855            mUidObservers.unregister(observer);
12856        }
12857    }
12858
12859    @Override
12860    public boolean convertFromTranslucent(IBinder token) {
12861        final long origId = Binder.clearCallingIdentity();
12862        try {
12863            synchronized (this) {
12864                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12865                if (r == null) {
12866                    return false;
12867                }
12868                final boolean translucentChanged = r.changeWindowTranslucency(true);
12869                if (translucentChanged) {
12870                    r.getStack().releaseBackgroundResources(r);
12871                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12872                }
12873                mWindowManager.setAppFullscreen(token, true);
12874                return translucentChanged;
12875            }
12876        } finally {
12877            Binder.restoreCallingIdentity(origId);
12878        }
12879    }
12880
12881    @Override
12882    public boolean convertToTranslucent(IBinder token, Bundle options) {
12883        final long origId = Binder.clearCallingIdentity();
12884        try {
12885            synchronized (this) {
12886                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12887                if (r == null) {
12888                    return false;
12889                }
12890                int index = r.task.mActivities.lastIndexOf(r);
12891                if (index > 0) {
12892                    ActivityRecord under = r.task.mActivities.get(index - 1);
12893                    under.returningOptions = ActivityOptions.fromBundle(options);
12894                }
12895                final boolean translucentChanged = r.changeWindowTranslucency(false);
12896                if (translucentChanged) {
12897                    r.getStack().convertActivityToTranslucent(r);
12898                }
12899                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12900                mWindowManager.setAppFullscreen(token, false);
12901                return translucentChanged;
12902            }
12903        } finally {
12904            Binder.restoreCallingIdentity(origId);
12905        }
12906    }
12907
12908    @Override
12909    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12910        final long origId = Binder.clearCallingIdentity();
12911        try {
12912            synchronized (this) {
12913                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12914                if (r != null) {
12915                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12916                }
12917            }
12918            return false;
12919        } finally {
12920            Binder.restoreCallingIdentity(origId);
12921        }
12922    }
12923
12924    @Override
12925    public boolean isBackgroundVisibleBehind(IBinder token) {
12926        final long origId = Binder.clearCallingIdentity();
12927        try {
12928            synchronized (this) {
12929                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12930                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12931                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12932                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12933                return visible;
12934            }
12935        } finally {
12936            Binder.restoreCallingIdentity(origId);
12937        }
12938    }
12939
12940    @Override
12941    public Bundle getActivityOptions(IBinder token) {
12942        final long origId = Binder.clearCallingIdentity();
12943        try {
12944            synchronized (this) {
12945                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12946                if (r != null) {
12947                    final ActivityOptions activityOptions = r.pendingOptions;
12948                    r.pendingOptions = null;
12949                    return activityOptions == null ? null : activityOptions.toBundle();
12950                }
12951                return null;
12952            }
12953        } finally {
12954            Binder.restoreCallingIdentity(origId);
12955        }
12956    }
12957
12958    @Override
12959    public void setImmersive(IBinder token, boolean immersive) {
12960        synchronized(this) {
12961            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12962            if (r == null) {
12963                throw new IllegalArgumentException();
12964            }
12965            r.immersive = immersive;
12966
12967            // update associated state if we're frontmost
12968            if (r == mStackSupervisor.getResumedActivityLocked()) {
12969                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12970                applyUpdateLockStateLocked(r);
12971            }
12972        }
12973    }
12974
12975    @Override
12976    public boolean isImmersive(IBinder token) {
12977        synchronized (this) {
12978            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12979            if (r == null) {
12980                throw new IllegalArgumentException();
12981            }
12982            return r.immersive;
12983        }
12984    }
12985
12986    public void setVrThread(int tid) {
12987        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12988            throw new UnsupportedOperationException("VR mode not supported on this device!");
12989        }
12990
12991        synchronized (this) {
12992            ProcessRecord proc;
12993            synchronized (mPidsSelfLocked) {
12994                final int pid = Binder.getCallingPid();
12995                proc = mPidsSelfLocked.get(pid);
12996
12997                if (proc != null && mInVrMode && tid >= 0) {
12998                    // ensure the tid belongs to the process
12999                    if (!Process.isThreadInProcess(pid, tid)) {
13000                        throw new IllegalArgumentException("VR thread does not belong to process");
13001                    }
13002
13003                    // reset existing VR thread to CFS if this thread still exists and belongs to
13004                    // the calling process
13005                    if (proc.vrThreadTid != 0
13006                            && Process.isThreadInProcess(pid, proc.vrThreadTid)) {
13007                        try {
13008                            Process.setThreadScheduler(proc.vrThreadTid, Process.SCHED_OTHER, 0);
13009                        } catch (IllegalArgumentException e) {
13010                            // Ignore this.  Only occurs in race condition where previous VR thread
13011                            // was destroyed during this method call.
13012                        }
13013                    }
13014
13015                    proc.vrThreadTid = tid;
13016
13017                    // promote to FIFO now if the tid is non-zero
13018                    try {
13019                        if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
13020                            proc.vrThreadTid > 0) {
13021                            Process.setThreadScheduler(proc.vrThreadTid,
13022                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
13023                        }
13024                    } catch (IllegalArgumentException e) {
13025                        Slog.e(TAG, "Failed to set scheduling policy, thread does"
13026                               + " not exist:\n" + e);
13027                    }
13028                }
13029            }
13030        }
13031    }
13032
13033    @Override
13034    public void setRenderThread(int tid) {
13035        synchronized (this) {
13036            ProcessRecord proc;
13037            synchronized (mPidsSelfLocked) {
13038                int pid = Binder.getCallingPid();
13039                proc = mPidsSelfLocked.get(pid);
13040                if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
13041                    // ensure the tid belongs to the process
13042                    if (!Process.isThreadInProcess(pid, tid)) {
13043                        throw new IllegalArgumentException(
13044                            "Render thread does not belong to process");
13045                    }
13046                    proc.renderThreadTid = tid;
13047                    if (DEBUG_OOM_ADJ) {
13048                        Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
13049                    }
13050                    // promote to FIFO now
13051                    if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
13052                        if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
13053                        if (mUseFifoUiScheduling) {
13054                            Process.setThreadScheduler(proc.renderThreadTid,
13055                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
13056                        } else {
13057                            Process.setThreadPriority(proc.renderThreadTid, -10);
13058                        }
13059                    }
13060                } else {
13061                    if (DEBUG_OOM_ADJ) {
13062                        Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
13063                               "PID: " + pid + ", TID: " + tid + " FIFO: " +
13064                               mUseFifoUiScheduling);
13065                    }
13066                }
13067            }
13068        }
13069    }
13070
13071    @Override
13072    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
13073        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13074            throw new UnsupportedOperationException("VR mode not supported on this device!");
13075        }
13076
13077        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13078
13079        ActivityRecord r;
13080        synchronized (this) {
13081            r = ActivityRecord.isInStackLocked(token);
13082        }
13083
13084        if (r == null) {
13085            throw new IllegalArgumentException();
13086        }
13087
13088        int err;
13089        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
13090                VrManagerInternal.NO_ERROR) {
13091            return err;
13092        }
13093
13094        synchronized(this) {
13095            r.requestedVrComponent = (enabled) ? packageName : null;
13096
13097            // Update associated state if this activity is currently focused
13098            if (r == mStackSupervisor.getResumedActivityLocked()) {
13099                applyUpdateVrModeLocked(r);
13100            }
13101            return 0;
13102        }
13103    }
13104
13105    @Override
13106    public boolean isVrModePackageEnabled(ComponentName packageName) {
13107        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13108            throw new UnsupportedOperationException("VR mode not supported on this device!");
13109        }
13110
13111        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13112
13113        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
13114                VrManagerInternal.NO_ERROR;
13115    }
13116
13117    public boolean isTopActivityImmersive() {
13118        enforceNotIsolatedCaller("startActivity");
13119        synchronized (this) {
13120            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
13121            return (r != null) ? r.immersive : false;
13122        }
13123    }
13124
13125    @Override
13126    public boolean isTopOfTask(IBinder token) {
13127        synchronized (this) {
13128            ActivityRecord r = ActivityRecord.isInStackLocked(token);
13129            if (r == null) {
13130                throw new IllegalArgumentException();
13131            }
13132            return r.task.getTopActivity() == r;
13133        }
13134    }
13135
13136    @Override
13137    public void setHasTopUi(boolean hasTopUi) throws RemoteException {
13138        if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
13139            String msg = "Permission Denial: setHasTopUi() from pid="
13140                    + Binder.getCallingPid()
13141                    + ", uid=" + Binder.getCallingUid()
13142                    + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
13143            Slog.w(TAG, msg);
13144            throw new SecurityException(msg);
13145        }
13146        final int pid = Binder.getCallingPid();
13147        final long origId = Binder.clearCallingIdentity();
13148        try {
13149            synchronized (this) {
13150                boolean changed = false;
13151                ProcessRecord pr;
13152                synchronized (mPidsSelfLocked) {
13153                    pr = mPidsSelfLocked.get(pid);
13154                    if (pr == null) {
13155                        Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
13156                        return;
13157                    }
13158                    if (pr.hasTopUi != hasTopUi) {
13159                        Slog.i(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
13160                        pr.hasTopUi = hasTopUi;
13161                        changed = true;
13162                    }
13163                }
13164                if (changed) {
13165                    updateOomAdjLocked(pr);
13166                }
13167            }
13168        } finally {
13169            Binder.restoreCallingIdentity(origId);
13170        }
13171    }
13172
13173    public final void enterSafeMode() {
13174        synchronized(this) {
13175            // It only makes sense to do this before the system is ready
13176            // and started launching other packages.
13177            if (!mSystemReady) {
13178                try {
13179                    AppGlobals.getPackageManager().enterSafeMode();
13180                } catch (RemoteException e) {
13181                }
13182            }
13183
13184            mSafeMode = true;
13185        }
13186    }
13187
13188    public final void showSafeModeOverlay() {
13189        View v = LayoutInflater.from(mContext).inflate(
13190                com.android.internal.R.layout.safe_mode, null);
13191        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
13192        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
13193        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
13194        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
13195        lp.gravity = Gravity.BOTTOM | Gravity.START;
13196        lp.format = v.getBackground().getOpacity();
13197        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
13198                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
13199        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
13200        ((WindowManager)mContext.getSystemService(
13201                Context.WINDOW_SERVICE)).addView(v, lp);
13202    }
13203
13204    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
13205        if (sender != null && !(sender instanceof PendingIntentRecord)) {
13206            return;
13207        }
13208        final PendingIntentRecord rec = (PendingIntentRecord)sender;
13209        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13210        synchronized (stats) {
13211            if (mBatteryStatsService.isOnBattery()) {
13212                mBatteryStatsService.enforceCallingPermission();
13213                int MY_UID = Binder.getCallingUid();
13214                final int uid;
13215                if (sender == null) {
13216                    uid = sourceUid;
13217                } else {
13218                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
13219                }
13220                BatteryStatsImpl.Uid.Pkg pkg =
13221                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
13222                            sourcePkg != null ? sourcePkg : rec.key.packageName);
13223                pkg.noteWakeupAlarmLocked(tag);
13224            }
13225        }
13226    }
13227
13228    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
13229        if (sender != null && !(sender instanceof PendingIntentRecord)) {
13230            return;
13231        }
13232        final PendingIntentRecord rec = (PendingIntentRecord)sender;
13233        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13234        synchronized (stats) {
13235            mBatteryStatsService.enforceCallingPermission();
13236            int MY_UID = Binder.getCallingUid();
13237            final int uid;
13238            if (sender == null) {
13239                uid = sourceUid;
13240            } else {
13241                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
13242            }
13243            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
13244        }
13245    }
13246
13247    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
13248        if (sender != null && !(sender instanceof PendingIntentRecord)) {
13249            return;
13250        }
13251        final PendingIntentRecord rec = (PendingIntentRecord)sender;
13252        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13253        synchronized (stats) {
13254            mBatteryStatsService.enforceCallingPermission();
13255            int MY_UID = Binder.getCallingUid();
13256            final int uid;
13257            if (sender == null) {
13258                uid = sourceUid;
13259            } else {
13260                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
13261            }
13262            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
13263        }
13264    }
13265
13266    public boolean killPids(int[] pids, String pReason, boolean secure) {
13267        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
13268            throw new SecurityException("killPids only available to the system");
13269        }
13270        String reason = (pReason == null) ? "Unknown" : pReason;
13271        // XXX Note: don't acquire main activity lock here, because the window
13272        // manager calls in with its locks held.
13273
13274        boolean killed = false;
13275        synchronized (mPidsSelfLocked) {
13276            int worstType = 0;
13277            for (int i=0; i<pids.length; i++) {
13278                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13279                if (proc != null) {
13280                    int type = proc.setAdj;
13281                    if (type > worstType) {
13282                        worstType = type;
13283                    }
13284                }
13285            }
13286
13287            // If the worst oom_adj is somewhere in the cached proc LRU range,
13288            // then constrain it so we will kill all cached procs.
13289            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
13290                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
13291                worstType = ProcessList.CACHED_APP_MIN_ADJ;
13292            }
13293
13294            // If this is not a secure call, don't let it kill processes that
13295            // are important.
13296            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
13297                worstType = ProcessList.SERVICE_ADJ;
13298            }
13299
13300            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
13301            for (int i=0; i<pids.length; i++) {
13302                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13303                if (proc == null) {
13304                    continue;
13305                }
13306                int adj = proc.setAdj;
13307                if (adj >= worstType && !proc.killedByAm) {
13308                    proc.kill(reason, true);
13309                    killed = true;
13310                }
13311            }
13312        }
13313        return killed;
13314    }
13315
13316    @Override
13317    public void killUid(int appId, int userId, String reason) {
13318        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
13319        synchronized (this) {
13320            final long identity = Binder.clearCallingIdentity();
13321            try {
13322                killPackageProcessesLocked(null, appId, userId,
13323                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
13324                        reason != null ? reason : "kill uid");
13325            } finally {
13326                Binder.restoreCallingIdentity(identity);
13327            }
13328        }
13329    }
13330
13331    @Override
13332    public boolean killProcessesBelowForeground(String reason) {
13333        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
13334            throw new SecurityException("killProcessesBelowForeground() only available to system");
13335        }
13336
13337        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
13338    }
13339
13340    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
13341        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
13342            throw new SecurityException("killProcessesBelowAdj() only available to system");
13343        }
13344
13345        boolean killed = false;
13346        synchronized (mPidsSelfLocked) {
13347            final int size = mPidsSelfLocked.size();
13348            for (int i = 0; i < size; i++) {
13349                final int pid = mPidsSelfLocked.keyAt(i);
13350                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13351                if (proc == null) continue;
13352
13353                final int adj = proc.setAdj;
13354                if (adj > belowAdj && !proc.killedByAm) {
13355                    proc.kill(reason, true);
13356                    killed = true;
13357                }
13358            }
13359        }
13360        return killed;
13361    }
13362
13363    @Override
13364    public void hang(final IBinder who, boolean allowRestart) {
13365        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13366                != PackageManager.PERMISSION_GRANTED) {
13367            throw new SecurityException("Requires permission "
13368                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13369        }
13370
13371        final IBinder.DeathRecipient death = new DeathRecipient() {
13372            @Override
13373            public void binderDied() {
13374                synchronized (this) {
13375                    notifyAll();
13376                }
13377            }
13378        };
13379
13380        try {
13381            who.linkToDeath(death, 0);
13382        } catch (RemoteException e) {
13383            Slog.w(TAG, "hang: given caller IBinder is already dead.");
13384            return;
13385        }
13386
13387        synchronized (this) {
13388            Watchdog.getInstance().setAllowRestart(allowRestart);
13389            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
13390            synchronized (death) {
13391                while (who.isBinderAlive()) {
13392                    try {
13393                        death.wait();
13394                    } catch (InterruptedException e) {
13395                    }
13396                }
13397            }
13398            Watchdog.getInstance().setAllowRestart(true);
13399        }
13400    }
13401
13402    @Override
13403    public void restart() {
13404        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13405                != PackageManager.PERMISSION_GRANTED) {
13406            throw new SecurityException("Requires permission "
13407                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13408        }
13409
13410        Log.i(TAG, "Sending shutdown broadcast...");
13411
13412        BroadcastReceiver br = new BroadcastReceiver() {
13413            @Override public void onReceive(Context context, Intent intent) {
13414                // Now the broadcast is done, finish up the low-level shutdown.
13415                Log.i(TAG, "Shutting down activity manager...");
13416                shutdown(10000);
13417                Log.i(TAG, "Shutdown complete, restarting!");
13418                Process.killProcess(Process.myPid());
13419                System.exit(10);
13420            }
13421        };
13422
13423        // First send the high-level shut down broadcast.
13424        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13425        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13426        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13427        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13428        mContext.sendOrderedBroadcastAsUser(intent,
13429                UserHandle.ALL, null, br, mHandler, 0, null, null);
13430        */
13431        br.onReceive(mContext, intent);
13432    }
13433
13434    private long getLowRamTimeSinceIdle(long now) {
13435        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13436    }
13437
13438    @Override
13439    public void performIdleMaintenance() {
13440        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13441                != PackageManager.PERMISSION_GRANTED) {
13442            throw new SecurityException("Requires permission "
13443                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13444        }
13445
13446        synchronized (this) {
13447            final long now = SystemClock.uptimeMillis();
13448            final long timeSinceLastIdle = now - mLastIdleTime;
13449            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13450            mLastIdleTime = now;
13451            mLowRamTimeSinceLastIdle = 0;
13452            if (mLowRamStartTime != 0) {
13453                mLowRamStartTime = now;
13454            }
13455
13456            StringBuilder sb = new StringBuilder(128);
13457            sb.append("Idle maintenance over ");
13458            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13459            sb.append(" low RAM for ");
13460            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13461            Slog.i(TAG, sb.toString());
13462
13463            // If at least 1/3 of our time since the last idle period has been spent
13464            // with RAM low, then we want to kill processes.
13465            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
13466
13467            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13468                ProcessRecord proc = mLruProcesses.get(i);
13469                if (proc.notCachedSinceIdle) {
13470                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
13471                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
13472                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
13473                        if (doKilling && proc.initialIdlePss != 0
13474                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
13475                            sb = new StringBuilder(128);
13476                            sb.append("Kill");
13477                            sb.append(proc.processName);
13478                            sb.append(" in idle maint: pss=");
13479                            sb.append(proc.lastPss);
13480                            sb.append(", swapPss=");
13481                            sb.append(proc.lastSwapPss);
13482                            sb.append(", initialPss=");
13483                            sb.append(proc.initialIdlePss);
13484                            sb.append(", period=");
13485                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13486                            sb.append(", lowRamPeriod=");
13487                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13488                            Slog.wtfQuiet(TAG, sb.toString());
13489                            proc.kill("idle maint (pss " + proc.lastPss
13490                                    + " from " + proc.initialIdlePss + ")", true);
13491                        }
13492                    }
13493                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
13494                        && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
13495                    proc.notCachedSinceIdle = true;
13496                    proc.initialIdlePss = 0;
13497                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
13498                            mTestPssMode, isSleepingLocked(), now);
13499                }
13500            }
13501
13502            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
13503            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
13504        }
13505    }
13506
13507    @Override
13508    public void sendIdleJobTrigger() {
13509        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13510                != PackageManager.PERMISSION_GRANTED) {
13511            throw new SecurityException("Requires permission "
13512                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13513        }
13514
13515        final long ident = Binder.clearCallingIdentity();
13516        try {
13517            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
13518                    .setPackage("android")
13519                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13520            broadcastIntent(null, intent, null, null, 0, null, null, null,
13521                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
13522        } finally {
13523            Binder.restoreCallingIdentity(ident);
13524        }
13525    }
13526
13527    private void retrieveSettings() {
13528        final ContentResolver resolver = mContext.getContentResolver();
13529        final boolean freeformWindowManagement =
13530                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
13531                        || Settings.Global.getInt(
13532                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
13533        final boolean supportsPictureInPicture =
13534                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
13535
13536        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
13537        final boolean supportsSplitScreenMultiWindow =
13538                ActivityManager.supportsSplitScreenMultiWindow();
13539        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
13540        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
13541        final boolean alwaysFinishActivities =
13542                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
13543        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
13544        final boolean forceResizable = Settings.Global.getInt(
13545                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
13546        final boolean supportsLeanbackOnly =
13547                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
13548
13549        // Transfer any global setting for forcing RTL layout, into a System Property
13550        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
13551
13552        final Configuration configuration = new Configuration();
13553        Settings.System.getConfiguration(resolver, configuration);
13554        if (forceRtl) {
13555            // This will take care of setting the correct layout direction flags
13556            configuration.setLayoutDirection(configuration.locale);
13557        }
13558
13559        synchronized (this) {
13560            mDebugApp = mOrigDebugApp = debugApp;
13561            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
13562            mAlwaysFinishActivities = alwaysFinishActivities;
13563            mSupportsLeanbackOnly = supportsLeanbackOnly;
13564            mForceResizableActivities = forceResizable;
13565            if (supportsMultiWindow || forceResizable) {
13566                mSupportsMultiWindow = true;
13567                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
13568            } else {
13569                mSupportsMultiWindow = false;
13570                mSupportsFreeformWindowManagement = false;
13571            }
13572            mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
13573            mSupportsPictureInPicture = supportsPictureInPicture;
13574            mWindowManager.setForceResizableTasks(mForceResizableActivities);
13575            mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
13576            // This happens before any activities are started, so we can change global configuration
13577            // in-place.
13578            updateConfigurationLocked(configuration, null, true);
13579            final Configuration globalConfig = getGlobalConfiguration();
13580            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
13581
13582            // Load resources only after the current configuration has been set.
13583            final Resources res = mContext.getResources();
13584            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
13585            mThumbnailWidth = res.getDimensionPixelSize(
13586                    com.android.internal.R.dimen.thumbnail_width);
13587            mThumbnailHeight = res.getDimensionPixelSize(
13588                    com.android.internal.R.dimen.thumbnail_height);
13589            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
13590                    com.android.internal.R.string.config_appsNotReportingCrashes));
13591            mUserController.mUserSwitchUiEnabled = !res.getBoolean(
13592                    com.android.internal.R.bool.config_customUserSwitchUi);
13593            if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
13594                mFullscreenThumbnailScale = (float) res
13595                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
13596                    (float) globalConfig.screenWidthDp;
13597            } else {
13598                mFullscreenThumbnailScale = res.getFraction(
13599                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13600            }
13601        }
13602    }
13603
13604    public void systemReady(final Runnable goingCallback, BootTimingsTraceLog traceLog) {
13605        traceLog.traceBegin("PhaseActivityManagerReady");
13606        synchronized(this) {
13607            if (mSystemReady) {
13608                // If we're done calling all the receivers, run the next "boot phase" passed in
13609                // by the SystemServer
13610                if (goingCallback != null) {
13611                    goingCallback.run();
13612                }
13613                return;
13614            }
13615
13616            mLocalDeviceIdleController
13617                    = LocalServices.getService(DeviceIdleController.LocalService.class);
13618            mAssistUtils = new AssistUtils(mContext);
13619
13620            // Make sure we have the current profile info, since it is needed for security checks.
13621            mUserController.onSystemReady();
13622            mRecentTasks.onSystemReadyLocked();
13623            mAppOpsService.systemReady();
13624            mSystemReady = true;
13625        }
13626
13627        ArrayList<ProcessRecord> procsToKill = null;
13628        synchronized(mPidsSelfLocked) {
13629            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13630                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13631                if (!isAllowedWhileBooting(proc.info)){
13632                    if (procsToKill == null) {
13633                        procsToKill = new ArrayList<ProcessRecord>();
13634                    }
13635                    procsToKill.add(proc);
13636                }
13637            }
13638        }
13639
13640        synchronized(this) {
13641            if (procsToKill != null) {
13642                for (int i=procsToKill.size()-1; i>=0; i--) {
13643                    ProcessRecord proc = procsToKill.get(i);
13644                    Slog.i(TAG, "Removing system update proc: " + proc);
13645                    removeProcessLocked(proc, true, false, "system update done");
13646                }
13647            }
13648
13649            // Now that we have cleaned up any update processes, we
13650            // are ready to start launching real processes and know that
13651            // we won't trample on them any more.
13652            mProcessesReady = true;
13653        }
13654
13655        Slog.i(TAG, "System now ready");
13656        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13657            SystemClock.uptimeMillis());
13658
13659        synchronized(this) {
13660            // Make sure we have no pre-ready processes sitting around.
13661
13662            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13663                ResolveInfo ri = mContext.getPackageManager()
13664                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13665                                STOCK_PM_FLAGS);
13666                CharSequence errorMsg = null;
13667                if (ri != null) {
13668                    ActivityInfo ai = ri.activityInfo;
13669                    ApplicationInfo app = ai.applicationInfo;
13670                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13671                        mTopAction = Intent.ACTION_FACTORY_TEST;
13672                        mTopData = null;
13673                        mTopComponent = new ComponentName(app.packageName,
13674                                ai.name);
13675                    } else {
13676                        errorMsg = mContext.getResources().getText(
13677                                com.android.internal.R.string.factorytest_not_system);
13678                    }
13679                } else {
13680                    errorMsg = mContext.getResources().getText(
13681                            com.android.internal.R.string.factorytest_no_action);
13682                }
13683                if (errorMsg != null) {
13684                    mTopAction = null;
13685                    mTopData = null;
13686                    mTopComponent = null;
13687                    Message msg = Message.obtain();
13688                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13689                    msg.getData().putCharSequence("msg", errorMsg);
13690                    mUiHandler.sendMessage(msg);
13691                }
13692            }
13693        }
13694
13695        retrieveSettings();
13696        final int currentUserId;
13697        synchronized (this) {
13698            currentUserId = mUserController.getCurrentUserIdLocked();
13699            readGrantedUriPermissionsLocked();
13700        }
13701
13702        if (goingCallback != null) goingCallback.run();
13703        traceLog.traceBegin("ActivityManagerStartApps");
13704        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13705                Integer.toString(currentUserId), currentUserId);
13706        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13707                Integer.toString(currentUserId), currentUserId);
13708        mSystemServiceManager.startUser(currentUserId);
13709
13710        synchronized (this) {
13711            // Only start up encryption-aware persistent apps; once user is
13712            // unlocked we'll come back around and start unaware apps
13713            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13714
13715            // Start up initial activity.
13716            mBooting = true;
13717            // Enable home activity for system user, so that the system can always boot. We don't
13718            // do this when the system user is not setup since the setup wizard should be the one
13719            // to handle home activity in this case.
13720            if (UserManager.isSplitSystemUser() &&
13721                    Settings.Secure.getInt(mContext.getContentResolver(),
13722                         Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
13723                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13724                try {
13725                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13726                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13727                            UserHandle.USER_SYSTEM);
13728                } catch (RemoteException e) {
13729                    throw e.rethrowAsRuntimeException();
13730                }
13731            }
13732            startHomeActivityLocked(currentUserId, "systemReady");
13733
13734            try {
13735                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13736                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13737                            + " data partition or your device will be unstable.");
13738                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13739                }
13740            } catch (RemoteException e) {
13741            }
13742
13743            if (!Build.isBuildConsistent()) {
13744                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13745                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13746            }
13747
13748            long ident = Binder.clearCallingIdentity();
13749            try {
13750                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13751                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13752                        | Intent.FLAG_RECEIVER_FOREGROUND);
13753                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13754                broadcastIntentLocked(null, null, intent,
13755                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13756                        null, false, false, MY_PID, Process.SYSTEM_UID,
13757                        currentUserId);
13758                intent = new Intent(Intent.ACTION_USER_STARTING);
13759                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13760                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13761                broadcastIntentLocked(null, null, intent,
13762                        null, new IIntentReceiver.Stub() {
13763                            @Override
13764                            public void performReceive(Intent intent, int resultCode, String data,
13765                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13766                                    throws RemoteException {
13767                            }
13768                        }, 0, null, null,
13769                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13770                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13771            } catch (Throwable t) {
13772                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13773            } finally {
13774                Binder.restoreCallingIdentity(ident);
13775            }
13776            mStackSupervisor.resumeFocusedStackTopActivityLocked();
13777            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13778            traceLog.traceEnd(); // ActivityManagerStartApps
13779            traceLog.traceEnd(); // PhaseActivityManagerReady
13780        }
13781    }
13782
13783    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13784        synchronized (this) {
13785            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13786        }
13787    }
13788
13789    void skipCurrentReceiverLocked(ProcessRecord app) {
13790        for (BroadcastQueue queue : mBroadcastQueues) {
13791            queue.skipCurrentReceiverLocked(app);
13792        }
13793    }
13794
13795    /**
13796     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13797     * The application process will exit immediately after this call returns.
13798     * @param app object of the crashing app, null for the system server
13799     * @param crashInfo describing the exception
13800     */
13801    public void handleApplicationCrash(IBinder app,
13802            ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
13803        ProcessRecord r = findAppProcess(app, "Crash");
13804        final String processName = app == null ? "system_server"
13805                : (r == null ? "unknown" : r.processName);
13806
13807        handleApplicationCrashInner("crash", r, processName, crashInfo);
13808    }
13809
13810    /* Native crash reporting uses this inner version because it needs to be somewhat
13811     * decoupled from the AM-managed cleanup lifecycle
13812     */
13813    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13814            ApplicationErrorReport.CrashInfo crashInfo) {
13815        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13816                UserHandle.getUserId(Binder.getCallingUid()), processName,
13817                r == null ? -1 : r.info.flags,
13818                crashInfo.exceptionClassName,
13819                crashInfo.exceptionMessage,
13820                crashInfo.throwFileName,
13821                crashInfo.throwLineNumber);
13822
13823        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13824
13825        mAppErrors.crashApplication(r, crashInfo);
13826    }
13827
13828    public void handleApplicationStrictModeViolation(
13829            IBinder app,
13830            int violationMask,
13831            StrictMode.ViolationInfo info) {
13832        ProcessRecord r = findAppProcess(app, "StrictMode");
13833        if (r == null) {
13834            return;
13835        }
13836
13837        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13838            Integer stackFingerprint = info.hashCode();
13839            boolean logIt = true;
13840            synchronized (mAlreadyLoggedViolatedStacks) {
13841                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13842                    logIt = false;
13843                    // TODO: sub-sample into EventLog for these, with
13844                    // the info.durationMillis?  Then we'd get
13845                    // the relative pain numbers, without logging all
13846                    // the stack traces repeatedly.  We'd want to do
13847                    // likewise in the client code, which also does
13848                    // dup suppression, before the Binder call.
13849                } else {
13850                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13851                        mAlreadyLoggedViolatedStacks.clear();
13852                    }
13853                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13854                }
13855            }
13856            if (logIt) {
13857                logStrictModeViolationToDropBox(r, info);
13858            }
13859        }
13860
13861        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13862            AppErrorResult result = new AppErrorResult();
13863            synchronized (this) {
13864                final long origId = Binder.clearCallingIdentity();
13865
13866                Message msg = Message.obtain();
13867                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13868                HashMap<String, Object> data = new HashMap<String, Object>();
13869                data.put("result", result);
13870                data.put("app", r);
13871                data.put("violationMask", violationMask);
13872                data.put("info", info);
13873                msg.obj = data;
13874                mUiHandler.sendMessage(msg);
13875
13876                Binder.restoreCallingIdentity(origId);
13877            }
13878            int res = result.get();
13879            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13880        }
13881    }
13882
13883    // Depending on the policy in effect, there could be a bunch of
13884    // these in quick succession so we try to batch these together to
13885    // minimize disk writes, number of dropbox entries, and maximize
13886    // compression, by having more fewer, larger records.
13887    private void logStrictModeViolationToDropBox(
13888            ProcessRecord process,
13889            StrictMode.ViolationInfo info) {
13890        if (info == null) {
13891            return;
13892        }
13893        final boolean isSystemApp = process == null ||
13894                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13895                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13896        final String processName = process == null ? "unknown" : process.processName;
13897        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13898        final DropBoxManager dbox = (DropBoxManager)
13899                mContext.getSystemService(Context.DROPBOX_SERVICE);
13900
13901        // Exit early if the dropbox isn't configured to accept this report type.
13902        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13903
13904        boolean bufferWasEmpty;
13905        boolean needsFlush;
13906        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13907        synchronized (sb) {
13908            bufferWasEmpty = sb.length() == 0;
13909            appendDropBoxProcessHeaders(process, processName, sb);
13910            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13911            sb.append("System-App: ").append(isSystemApp).append("\n");
13912            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13913            if (info.violationNumThisLoop != 0) {
13914                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13915            }
13916            if (info.numAnimationsRunning != 0) {
13917                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13918            }
13919            if (info.broadcastIntentAction != null) {
13920                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13921            }
13922            if (info.durationMillis != -1) {
13923                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13924            }
13925            if (info.numInstances != -1) {
13926                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13927            }
13928            if (info.tags != null) {
13929                for (String tag : info.tags) {
13930                    sb.append("Span-Tag: ").append(tag).append("\n");
13931                }
13932            }
13933            sb.append("\n");
13934            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13935                sb.append(info.crashInfo.stackTrace);
13936                sb.append("\n");
13937            }
13938            if (info.message != null) {
13939                sb.append(info.message);
13940                sb.append("\n");
13941            }
13942
13943            // Only buffer up to ~64k.  Various logging bits truncate
13944            // things at 128k.
13945            needsFlush = (sb.length() > 64 * 1024);
13946        }
13947
13948        // Flush immediately if the buffer's grown too large, or this
13949        // is a non-system app.  Non-system apps are isolated with a
13950        // different tag & policy and not batched.
13951        //
13952        // Batching is useful during internal testing with
13953        // StrictMode settings turned up high.  Without batching,
13954        // thousands of separate files could be created on boot.
13955        if (!isSystemApp || needsFlush) {
13956            new Thread("Error dump: " + dropboxTag) {
13957                @Override
13958                public void run() {
13959                    String report;
13960                    synchronized (sb) {
13961                        report = sb.toString();
13962                        sb.delete(0, sb.length());
13963                        sb.trimToSize();
13964                    }
13965                    if (report.length() != 0) {
13966                        dbox.addText(dropboxTag, report);
13967                    }
13968                }
13969            }.start();
13970            return;
13971        }
13972
13973        // System app batching:
13974        if (!bufferWasEmpty) {
13975            // An existing dropbox-writing thread is outstanding, so
13976            // we don't need to start it up.  The existing thread will
13977            // catch the buffer appends we just did.
13978            return;
13979        }
13980
13981        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13982        // (After this point, we shouldn't access AMS internal data structures.)
13983        new Thread("Error dump: " + dropboxTag) {
13984            @Override
13985            public void run() {
13986                // 5 second sleep to let stacks arrive and be batched together
13987                try {
13988                    Thread.sleep(5000);  // 5 seconds
13989                } catch (InterruptedException e) {}
13990
13991                String errorReport;
13992                synchronized (mStrictModeBuffer) {
13993                    errorReport = mStrictModeBuffer.toString();
13994                    if (errorReport.length() == 0) {
13995                        return;
13996                    }
13997                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13998                    mStrictModeBuffer.trimToSize();
13999                }
14000                dbox.addText(dropboxTag, errorReport);
14001            }
14002        }.start();
14003    }
14004
14005    /**
14006     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
14007     * @param app object of the crashing app, null for the system server
14008     * @param tag reported by the caller
14009     * @param system whether this wtf is coming from the system
14010     * @param crashInfo describing the context of the error
14011     * @return true if the process should exit immediately (WTF is fatal)
14012     */
14013    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
14014            final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14015        final int callingUid = Binder.getCallingUid();
14016        final int callingPid = Binder.getCallingPid();
14017
14018        if (system) {
14019            // If this is coming from the system, we could very well have low-level
14020            // system locks held, so we want to do this all asynchronously.  And we
14021            // never want this to become fatal, so there is that too.
14022            mHandler.post(new Runnable() {
14023                @Override public void run() {
14024                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
14025                }
14026            });
14027            return false;
14028        }
14029
14030        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
14031                crashInfo);
14032
14033        final boolean isFatal = "eng".equals(Build.TYPE) || Settings.Global
14034                .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
14035        final boolean isSystem = (r == null) || r.persistent;
14036
14037        if (isFatal && !isSystem) {
14038            mAppErrors.crashApplication(r, crashInfo);
14039            return true;
14040        } else {
14041            return false;
14042        }
14043    }
14044
14045    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
14046            final ApplicationErrorReport.CrashInfo crashInfo) {
14047        final ProcessRecord r = findAppProcess(app, "WTF");
14048        final String processName = app == null ? "system_server"
14049                : (r == null ? "unknown" : r.processName);
14050
14051        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
14052                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
14053
14054        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
14055
14056        return r;
14057    }
14058
14059    /**
14060     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
14061     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
14062     */
14063    private ProcessRecord findAppProcess(IBinder app, String reason) {
14064        if (app == null) {
14065            return null;
14066        }
14067
14068        synchronized (this) {
14069            final int NP = mProcessNames.getMap().size();
14070            for (int ip=0; ip<NP; ip++) {
14071                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
14072                final int NA = apps.size();
14073                for (int ia=0; ia<NA; ia++) {
14074                    ProcessRecord p = apps.valueAt(ia);
14075                    if (p.thread != null && p.thread.asBinder() == app) {
14076                        return p;
14077                    }
14078                }
14079            }
14080
14081            Slog.w(TAG, "Can't find mystery application for " + reason
14082                    + " from pid=" + Binder.getCallingPid()
14083                    + " uid=" + Binder.getCallingUid() + ": " + app);
14084            return null;
14085        }
14086    }
14087
14088    /**
14089     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
14090     * to append various headers to the dropbox log text.
14091     */
14092    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
14093            StringBuilder sb) {
14094        // Watchdog thread ends up invoking this function (with
14095        // a null ProcessRecord) to add the stack file to dropbox.
14096        // Do not acquire a lock on this (am) in such cases, as it
14097        // could cause a potential deadlock, if and when watchdog
14098        // is invoked due to unavailability of lock on am and it
14099        // would prevent watchdog from killing system_server.
14100        if (process == null) {
14101            sb.append("Process: ").append(processName).append("\n");
14102            return;
14103        }
14104        // Note: ProcessRecord 'process' is guarded by the service
14105        // instance.  (notably process.pkgList, which could otherwise change
14106        // concurrently during execution of this method)
14107        synchronized (this) {
14108            sb.append("Process: ").append(processName).append("\n");
14109            int flags = process.info.flags;
14110            IPackageManager pm = AppGlobals.getPackageManager();
14111            sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
14112            for (int ip=0; ip<process.pkgList.size(); ip++) {
14113                String pkg = process.pkgList.keyAt(ip);
14114                sb.append("Package: ").append(pkg);
14115                try {
14116                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
14117                    if (pi != null) {
14118                        sb.append(" v").append(pi.versionCode);
14119                        if (pi.versionName != null) {
14120                            sb.append(" (").append(pi.versionName).append(")");
14121                        }
14122                    }
14123                } catch (RemoteException e) {
14124                    Slog.e(TAG, "Error getting package info: " + pkg, e);
14125                }
14126                sb.append("\n");
14127            }
14128        }
14129    }
14130
14131    private static String processClass(ProcessRecord process) {
14132        if (process == null || process.pid == MY_PID) {
14133            return "system_server";
14134        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
14135            return "system_app";
14136        } else {
14137            return "data_app";
14138        }
14139    }
14140
14141    private volatile long mWtfClusterStart;
14142    private volatile int mWtfClusterCount;
14143
14144    /**
14145     * Write a description of an error (crash, WTF, ANR) to the drop box.
14146     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
14147     * @param process which caused the error, null means the system server
14148     * @param activity which triggered the error, null if unknown
14149     * @param parent activity related to the error, null if unknown
14150     * @param subject line related to the error, null if absent
14151     * @param report in long form describing the error, null if absent
14152     * @param dataFile text file to include in the report, null if none
14153     * @param crashInfo giving an application stack trace, null if absent
14154     */
14155    public void addErrorToDropBox(String eventType,
14156            ProcessRecord process, String processName, ActivityRecord activity,
14157            ActivityRecord parent, String subject,
14158            final String report, final File dataFile,
14159            final ApplicationErrorReport.CrashInfo crashInfo) {
14160        // NOTE -- this must never acquire the ActivityManagerService lock,
14161        // otherwise the watchdog may be prevented from resetting the system.
14162
14163        // Bail early if not published yet
14164        if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
14165        final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
14166
14167        // Exit early if the dropbox isn't configured to accept this report type.
14168        final String dropboxTag = processClass(process) + "_" + eventType;
14169        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14170
14171        // Rate-limit how often we're willing to do the heavy lifting below to
14172        // collect and record logs; currently 5 logs per 10 second period.
14173        final long now = SystemClock.elapsedRealtime();
14174        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
14175            mWtfClusterStart = now;
14176            mWtfClusterCount = 1;
14177        } else {
14178            if (mWtfClusterCount++ >= 5) return;
14179        }
14180
14181        final StringBuilder sb = new StringBuilder(1024);
14182        appendDropBoxProcessHeaders(process, processName, sb);
14183        if (process != null) {
14184            sb.append("Foreground: ")
14185                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
14186                    .append("\n");
14187        }
14188        if (activity != null) {
14189            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
14190        }
14191        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
14192            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
14193        }
14194        if (parent != null && parent != activity) {
14195            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
14196        }
14197        if (subject != null) {
14198            sb.append("Subject: ").append(subject).append("\n");
14199        }
14200        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14201        if (Debug.isDebuggerConnected()) {
14202            sb.append("Debugger: Connected\n");
14203        }
14204        sb.append("\n");
14205
14206        // Do the rest in a worker thread to avoid blocking the caller on I/O
14207        // (After this point, we shouldn't access AMS internal data structures.)
14208        Thread worker = new Thread("Error dump: " + dropboxTag) {
14209            @Override
14210            public void run() {
14211                if (report != null) {
14212                    sb.append(report);
14213                }
14214
14215                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
14216                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
14217                int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
14218                        - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
14219
14220                if (dataFile != null && maxDataFileSize > 0) {
14221                    try {
14222                        sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
14223                                    "\n\n[[TRUNCATED]]"));
14224                    } catch (IOException e) {
14225                        Slog.e(TAG, "Error reading " + dataFile, e);
14226                    }
14227                }
14228                if (crashInfo != null && crashInfo.stackTrace != null) {
14229                    sb.append(crashInfo.stackTrace);
14230                }
14231
14232                if (lines > 0) {
14233                    sb.append("\n");
14234
14235                    // Merge several logcat streams, and take the last N lines
14236                    InputStreamReader input = null;
14237                    try {
14238                        java.lang.Process logcat = new ProcessBuilder(
14239                                "/system/bin/timeout", "-k", "15s", "10s",
14240                                "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
14241                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
14242                                        .redirectErrorStream(true).start();
14243
14244                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
14245                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
14246                        input = new InputStreamReader(logcat.getInputStream());
14247
14248                        int num;
14249                        char[] buf = new char[8192];
14250                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
14251                    } catch (IOException e) {
14252                        Slog.e(TAG, "Error running logcat", e);
14253                    } finally {
14254                        if (input != null) try { input.close(); } catch (IOException e) {}
14255                    }
14256                }
14257
14258                dbox.addText(dropboxTag, sb.toString());
14259            }
14260        };
14261
14262        if (process == null) {
14263            // If process is null, we are being called from some internal code
14264            // and may be about to die -- run this synchronously.
14265            worker.run();
14266        } else {
14267            worker.start();
14268        }
14269    }
14270
14271    @Override
14272    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
14273        enforceNotIsolatedCaller("getProcessesInErrorState");
14274        // assume our apps are happy - lazy create the list
14275        List<ActivityManager.ProcessErrorStateInfo> errList = null;
14276
14277        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14278                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
14279        int userId = UserHandle.getUserId(Binder.getCallingUid());
14280
14281        synchronized (this) {
14282
14283            // iterate across all processes
14284            for (int i=mLruProcesses.size()-1; i>=0; i--) {
14285                ProcessRecord app = mLruProcesses.get(i);
14286                if (!allUsers && app.userId != userId) {
14287                    continue;
14288                }
14289                if ((app.thread != null) && (app.crashing || app.notResponding)) {
14290                    // This one's in trouble, so we'll generate a report for it
14291                    // crashes are higher priority (in case there's a crash *and* an anr)
14292                    ActivityManager.ProcessErrorStateInfo report = null;
14293                    if (app.crashing) {
14294                        report = app.crashingReport;
14295                    } else if (app.notResponding) {
14296                        report = app.notRespondingReport;
14297                    }
14298
14299                    if (report != null) {
14300                        if (errList == null) {
14301                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
14302                        }
14303                        errList.add(report);
14304                    } else {
14305                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
14306                                " crashing = " + app.crashing +
14307                                " notResponding = " + app.notResponding);
14308                    }
14309                }
14310            }
14311        }
14312
14313        return errList;
14314    }
14315
14316    static int procStateToImportance(int procState, int memAdj,
14317            ActivityManager.RunningAppProcessInfo currApp) {
14318        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
14319        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
14320            currApp.lru = memAdj;
14321        } else {
14322            currApp.lru = 0;
14323        }
14324        return imp;
14325    }
14326
14327    private void fillInProcMemInfo(ProcessRecord app,
14328            ActivityManager.RunningAppProcessInfo outInfo) {
14329        outInfo.pid = app.pid;
14330        outInfo.uid = app.info.uid;
14331        if (mHeavyWeightProcess == app) {
14332            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
14333        }
14334        if (app.persistent) {
14335            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
14336        }
14337        if (app.activities.size() > 0) {
14338            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
14339        }
14340        outInfo.lastTrimLevel = app.trimMemoryLevel;
14341        int adj = app.curAdj;
14342        int procState = app.curProcState;
14343        outInfo.importance = procStateToImportance(procState, adj, outInfo);
14344        outInfo.importanceReasonCode = app.adjTypeCode;
14345        outInfo.processState = app.curProcState;
14346    }
14347
14348    @Override
14349    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
14350        enforceNotIsolatedCaller("getRunningAppProcesses");
14351
14352        final int callingUid = Binder.getCallingUid();
14353
14354        // Lazy instantiation of list
14355        List<ActivityManager.RunningAppProcessInfo> runList = null;
14356        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14357                callingUid) == PackageManager.PERMISSION_GRANTED;
14358        final int userId = UserHandle.getUserId(callingUid);
14359        final boolean allUids = isGetTasksAllowed(
14360                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
14361
14362        synchronized (this) {
14363            // Iterate across all processes
14364            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14365                ProcessRecord app = mLruProcesses.get(i);
14366                if ((!allUsers && app.userId != userId)
14367                        || (!allUids && app.uid != callingUid)) {
14368                    continue;
14369                }
14370                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
14371                    // Generate process state info for running application
14372                    ActivityManager.RunningAppProcessInfo currApp =
14373                        new ActivityManager.RunningAppProcessInfo(app.processName,
14374                                app.pid, app.getPackageList());
14375                    fillInProcMemInfo(app, currApp);
14376                    if (app.adjSource instanceof ProcessRecord) {
14377                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
14378                        currApp.importanceReasonImportance =
14379                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
14380                                        app.adjSourceProcState);
14381                    } else if (app.adjSource instanceof ActivityRecord) {
14382                        ActivityRecord r = (ActivityRecord)app.adjSource;
14383                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
14384                    }
14385                    if (app.adjTarget instanceof ComponentName) {
14386                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
14387                    }
14388                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
14389                    //        + " lru=" + currApp.lru);
14390                    if (runList == null) {
14391                        runList = new ArrayList<>();
14392                    }
14393                    runList.add(currApp);
14394                }
14395            }
14396        }
14397        return runList;
14398    }
14399
14400    @Override
14401    public List<ApplicationInfo> getRunningExternalApplications() {
14402        enforceNotIsolatedCaller("getRunningExternalApplications");
14403        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14404        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14405        if (runningApps != null && runningApps.size() > 0) {
14406            Set<String> extList = new HashSet<String>();
14407            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14408                if (app.pkgList != null) {
14409                    for (String pkg : app.pkgList) {
14410                        extList.add(pkg);
14411                    }
14412                }
14413            }
14414            IPackageManager pm = AppGlobals.getPackageManager();
14415            for (String pkg : extList) {
14416                try {
14417                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14418                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14419                        retList.add(info);
14420                    }
14421                } catch (RemoteException e) {
14422                }
14423            }
14424        }
14425        return retList;
14426    }
14427
14428    @Override
14429    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
14430        enforceNotIsolatedCaller("getMyMemoryState");
14431        synchronized (this) {
14432            ProcessRecord proc;
14433            synchronized (mPidsSelfLocked) {
14434                proc = mPidsSelfLocked.get(Binder.getCallingPid());
14435            }
14436            fillInProcMemInfo(proc, outInfo);
14437        }
14438    }
14439
14440    @Override
14441    public int getMemoryTrimLevel() {
14442        enforceNotIsolatedCaller("getMyMemoryState");
14443        synchronized (this) {
14444            return mLastMemoryLevel;
14445        }
14446    }
14447
14448    @Override
14449    public void onShellCommand(FileDescriptor in, FileDescriptor out,
14450            FileDescriptor err, String[] args, ShellCallback callback,
14451            ResultReceiver resultReceiver) {
14452        (new ActivityManagerShellCommand(this, false)).exec(
14453                this, in, out, err, args, callback, resultReceiver);
14454    }
14455
14456    @Override
14457    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
14458        if (checkCallingPermission(android.Manifest.permission.DUMP)
14459                != PackageManager.PERMISSION_GRANTED) {
14460            pw.println("Permission Denial: can't dump ActivityManager from from pid="
14461                    + Binder.getCallingPid()
14462                    + ", uid=" + Binder.getCallingUid()
14463                    + " without permission "
14464                    + android.Manifest.permission.DUMP);
14465            return;
14466        }
14467
14468        boolean dumpAll = false;
14469        boolean dumpClient = false;
14470        boolean dumpCheckin = false;
14471        boolean dumpCheckinFormat = false;
14472        boolean dumpVisibleStacksOnly = false;
14473        boolean dumpFocusedStackOnly = false;
14474        String dumpPackage = null;
14475
14476        int opti = 0;
14477        while (opti < args.length) {
14478            String opt = args[opti];
14479            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14480                break;
14481            }
14482            opti++;
14483            if ("-a".equals(opt)) {
14484                dumpAll = true;
14485            } else if ("-c".equals(opt)) {
14486                dumpClient = true;
14487            } else if ("-v".equals(opt)) {
14488                dumpVisibleStacksOnly = true;
14489            } else if ("-f".equals(opt)) {
14490                dumpFocusedStackOnly = true;
14491            } else if ("-p".equals(opt)) {
14492                if (opti < args.length) {
14493                    dumpPackage = args[opti];
14494                    opti++;
14495                } else {
14496                    pw.println("Error: -p option requires package argument");
14497                    return;
14498                }
14499                dumpClient = true;
14500            } else if ("--checkin".equals(opt)) {
14501                dumpCheckin = dumpCheckinFormat = true;
14502            } else if ("-C".equals(opt)) {
14503                dumpCheckinFormat = true;
14504            } else if ("-h".equals(opt)) {
14505                ActivityManagerShellCommand.dumpHelp(pw, true);
14506                return;
14507            } else {
14508                pw.println("Unknown argument: " + opt + "; use -h for help");
14509            }
14510        }
14511
14512        long origId = Binder.clearCallingIdentity();
14513        boolean more = false;
14514        // Is the caller requesting to dump a particular piece of data?
14515        if (opti < args.length) {
14516            String cmd = args[opti];
14517            opti++;
14518            if ("activities".equals(cmd) || "a".equals(cmd)) {
14519                synchronized (this) {
14520                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14521                }
14522            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
14523                synchronized (this) {
14524                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
14525                }
14526            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
14527                String[] newArgs;
14528                String name;
14529                if (opti >= args.length) {
14530                    name = null;
14531                    newArgs = EMPTY_STRING_ARRAY;
14532                } else {
14533                    dumpPackage = args[opti];
14534                    opti++;
14535                    newArgs = new String[args.length - opti];
14536                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14537                            args.length - opti);
14538                }
14539                synchronized (this) {
14540                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
14541                }
14542            } else if ("broadcast-stats".equals(cmd)) {
14543                String[] newArgs;
14544                String name;
14545                if (opti >= args.length) {
14546                    name = null;
14547                    newArgs = EMPTY_STRING_ARRAY;
14548                } else {
14549                    dumpPackage = args[opti];
14550                    opti++;
14551                    newArgs = new String[args.length - opti];
14552                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14553                            args.length - opti);
14554                }
14555                synchronized (this) {
14556                    if (dumpCheckinFormat) {
14557                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
14558                                dumpPackage);
14559                    } else {
14560                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
14561                    }
14562                }
14563            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
14564                String[] newArgs;
14565                String name;
14566                if (opti >= args.length) {
14567                    name = null;
14568                    newArgs = EMPTY_STRING_ARRAY;
14569                } else {
14570                    dumpPackage = args[opti];
14571                    opti++;
14572                    newArgs = new String[args.length - opti];
14573                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14574                            args.length - opti);
14575                }
14576                synchronized (this) {
14577                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
14578                }
14579            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
14580                String[] newArgs;
14581                String name;
14582                if (opti >= args.length) {
14583                    name = null;
14584                    newArgs = EMPTY_STRING_ARRAY;
14585                } else {
14586                    dumpPackage = args[opti];
14587                    opti++;
14588                    newArgs = new String[args.length - opti];
14589                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14590                            args.length - opti);
14591                }
14592                synchronized (this) {
14593                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
14594                }
14595            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
14596                synchronized (this) {
14597                    dumpOomLocked(fd, pw, args, opti, true);
14598                }
14599            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
14600                synchronized (this) {
14601                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
14602                }
14603            } else if ("provider".equals(cmd)) {
14604                String[] newArgs;
14605                String name;
14606                if (opti >= args.length) {
14607                    name = null;
14608                    newArgs = EMPTY_STRING_ARRAY;
14609                } else {
14610                    name = args[opti];
14611                    opti++;
14612                    newArgs = new String[args.length - opti];
14613                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14614                }
14615                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
14616                    pw.println("No providers match: " + name);
14617                    pw.println("Use -h for help.");
14618                }
14619            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
14620                synchronized (this) {
14621                    dumpProvidersLocked(fd, pw, args, opti, true, null);
14622                }
14623            } else if ("service".equals(cmd)) {
14624                String[] newArgs;
14625                String name;
14626                if (opti >= args.length) {
14627                    name = null;
14628                    newArgs = EMPTY_STRING_ARRAY;
14629                } else {
14630                    name = args[opti];
14631                    opti++;
14632                    newArgs = new String[args.length - opti];
14633                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14634                            args.length - opti);
14635                }
14636                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14637                    pw.println("No services match: " + name);
14638                    pw.println("Use -h for help.");
14639                }
14640            } else if ("package".equals(cmd)) {
14641                String[] newArgs;
14642                if (opti >= args.length) {
14643                    pw.println("package: no package name specified");
14644                    pw.println("Use -h for help.");
14645                } else {
14646                    dumpPackage = args[opti];
14647                    opti++;
14648                    newArgs = new String[args.length - opti];
14649                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14650                            args.length - opti);
14651                    args = newArgs;
14652                    opti = 0;
14653                    more = true;
14654                }
14655            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14656                synchronized (this) {
14657                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14658                }
14659            } else if ("settings".equals(cmd)) {
14660                synchronized (this) {
14661                    mConstants.dump(pw);
14662                }
14663            } else if ("services".equals(cmd) || "s".equals(cmd)) {
14664                if (dumpClient) {
14665                    ActiveServices.ServiceDumper dumper;
14666                    synchronized (this) {
14667                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14668                                dumpPackage);
14669                    }
14670                    dumper.dumpWithClient();
14671                } else {
14672                    synchronized (this) {
14673                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14674                                dumpPackage).dumpLocked();
14675                    }
14676                }
14677            } else if ("locks".equals(cmd)) {
14678                LockGuard.dump(fd, pw, args);
14679            } else {
14680                // Dumping a single activity?
14681                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly,
14682                        dumpFocusedStackOnly)) {
14683                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14684                    int res = shell.exec(this, null, fd, null, args, null,
14685                            new ResultReceiver(null));
14686                    if (res < 0) {
14687                        pw.println("Bad activity command, or no activities match: " + cmd);
14688                        pw.println("Use -h for help.");
14689                    }
14690                }
14691            }
14692            if (!more) {
14693                Binder.restoreCallingIdentity(origId);
14694                return;
14695            }
14696        }
14697
14698        // No piece of data specified, dump everything.
14699        if (dumpCheckinFormat) {
14700            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14701        } else if (dumpClient) {
14702            ActiveServices.ServiceDumper sdumper;
14703            synchronized (this) {
14704                mConstants.dump(pw);
14705                pw.println();
14706                if (dumpAll) {
14707                    pw.println("-------------------------------------------------------------------------------");
14708                }
14709                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14710                pw.println();
14711                if (dumpAll) {
14712                    pw.println("-------------------------------------------------------------------------------");
14713                }
14714                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14715                pw.println();
14716                if (dumpAll) {
14717                    pw.println("-------------------------------------------------------------------------------");
14718                }
14719                if (dumpAll || dumpPackage != null) {
14720                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14721                    pw.println();
14722                    if (dumpAll) {
14723                        pw.println("-------------------------------------------------------------------------------");
14724                    }
14725                }
14726                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14727                pw.println();
14728                if (dumpAll) {
14729                    pw.println("-------------------------------------------------------------------------------");
14730                }
14731                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14732                pw.println();
14733                if (dumpAll) {
14734                    pw.println("-------------------------------------------------------------------------------");
14735                }
14736                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14737                        dumpPackage);
14738            }
14739            sdumper.dumpWithClient();
14740            pw.println();
14741            synchronized (this) {
14742                if (dumpAll) {
14743                    pw.println("-------------------------------------------------------------------------------");
14744                }
14745                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14746                pw.println();
14747                if (dumpAll) {
14748                    pw.println("-------------------------------------------------------------------------------");
14749                }
14750                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14751                if (mAssociations.size() > 0) {
14752                    pw.println();
14753                    if (dumpAll) {
14754                        pw.println("-------------------------------------------------------------------------------");
14755                    }
14756                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14757                }
14758                pw.println();
14759                if (dumpAll) {
14760                    pw.println("-------------------------------------------------------------------------------");
14761                }
14762                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14763            }
14764
14765        } else {
14766            synchronized (this) {
14767                mConstants.dump(pw);
14768                pw.println();
14769                if (dumpAll) {
14770                    pw.println("-------------------------------------------------------------------------------");
14771                }
14772                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14773                pw.println();
14774                if (dumpAll) {
14775                    pw.println("-------------------------------------------------------------------------------");
14776                }
14777                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14778                pw.println();
14779                if (dumpAll) {
14780                    pw.println("-------------------------------------------------------------------------------");
14781                }
14782                if (dumpAll || dumpPackage != null) {
14783                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14784                    pw.println();
14785                    if (dumpAll) {
14786                        pw.println("-------------------------------------------------------------------------------");
14787                    }
14788                }
14789                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14790                pw.println();
14791                if (dumpAll) {
14792                    pw.println("-------------------------------------------------------------------------------");
14793                }
14794                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14795                pw.println();
14796                if (dumpAll) {
14797                    pw.println("-------------------------------------------------------------------------------");
14798                }
14799                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14800                        .dumpLocked();
14801                pw.println();
14802                if (dumpAll) {
14803                    pw.println("-------------------------------------------------------------------------------");
14804                }
14805                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14806                pw.println();
14807                if (dumpAll) {
14808                    pw.println("-------------------------------------------------------------------------------");
14809                }
14810                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14811                if (mAssociations.size() > 0) {
14812                    pw.println();
14813                    if (dumpAll) {
14814                        pw.println("-------------------------------------------------------------------------------");
14815                    }
14816                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14817                }
14818                pw.println();
14819                if (dumpAll) {
14820                    pw.println("-------------------------------------------------------------------------------");
14821                }
14822                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14823            }
14824        }
14825        Binder.restoreCallingIdentity(origId);
14826    }
14827
14828    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14829            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14830        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14831
14832        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14833                dumpPackage);
14834        boolean needSep = printedAnything;
14835
14836        boolean printed = ActivityStackSupervisor.printThisActivity(pw,
14837                mStackSupervisor.getResumedActivityLocked(),
14838                dumpPackage, needSep, "  ResumedActivity: ");
14839        if (printed) {
14840            printedAnything = true;
14841            needSep = false;
14842        }
14843
14844        if (dumpPackage == null) {
14845            if (needSep) {
14846                pw.println();
14847            }
14848            needSep = true;
14849            printedAnything = true;
14850            mStackSupervisor.dump(pw, "  ");
14851        }
14852
14853        if (!printedAnything) {
14854            pw.println("  (nothing)");
14855        }
14856    }
14857
14858    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14859            int opti, boolean dumpAll, String dumpPackage) {
14860        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14861
14862        boolean printedAnything = false;
14863
14864        if (mRecentTasks != null && mRecentTasks.size() > 0) {
14865            boolean printedHeader = false;
14866
14867            final int N = mRecentTasks.size();
14868            for (int i=0; i<N; i++) {
14869                TaskRecord tr = mRecentTasks.get(i);
14870                if (dumpPackage != null) {
14871                    if (tr.realActivity == null ||
14872                            !dumpPackage.equals(tr.realActivity.getPackageName())) {
14873                        continue;
14874                    }
14875                }
14876                if (!printedHeader) {
14877                    pw.println("  Recent tasks:");
14878                    printedHeader = true;
14879                    printedAnything = true;
14880                }
14881                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14882                        pw.println(tr);
14883                if (dumpAll) {
14884                    mRecentTasks.get(i).dump(pw, "    ");
14885                }
14886            }
14887        }
14888
14889        if (!printedAnything) {
14890            pw.println("  (nothing)");
14891        }
14892    }
14893
14894    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14895            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14896        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14897
14898        int dumpUid = 0;
14899        if (dumpPackage != null) {
14900            IPackageManager pm = AppGlobals.getPackageManager();
14901            try {
14902                dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
14903            } catch (RemoteException e) {
14904            }
14905        }
14906
14907        boolean printedAnything = false;
14908
14909        final long now = SystemClock.uptimeMillis();
14910
14911        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14912            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14913                    = mAssociations.valueAt(i1);
14914            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14915                SparseArray<ArrayMap<String, Association>> sourceUids
14916                        = targetComponents.valueAt(i2);
14917                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14918                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14919                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14920                        Association ass = sourceProcesses.valueAt(i4);
14921                        if (dumpPackage != null) {
14922                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14923                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14924                                continue;
14925                            }
14926                        }
14927                        printedAnything = true;
14928                        pw.print("  ");
14929                        pw.print(ass.mTargetProcess);
14930                        pw.print("/");
14931                        UserHandle.formatUid(pw, ass.mTargetUid);
14932                        pw.print(" <- ");
14933                        pw.print(ass.mSourceProcess);
14934                        pw.print("/");
14935                        UserHandle.formatUid(pw, ass.mSourceUid);
14936                        pw.println();
14937                        pw.print("    via ");
14938                        pw.print(ass.mTargetComponent.flattenToShortString());
14939                        pw.println();
14940                        pw.print("    ");
14941                        long dur = ass.mTime;
14942                        if (ass.mNesting > 0) {
14943                            dur += now - ass.mStartTime;
14944                        }
14945                        TimeUtils.formatDuration(dur, pw);
14946                        pw.print(" (");
14947                        pw.print(ass.mCount);
14948                        pw.print(" times)");
14949                        pw.print("  ");
14950                        for (int i=0; i<ass.mStateTimes.length; i++) {
14951                            long amt = ass.mStateTimes[i];
14952                            if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
14953                                amt += now - ass.mLastStateUptime;
14954                            }
14955                            if (amt != 0) {
14956                                pw.print(" ");
14957                                pw.print(ProcessList.makeProcStateString(
14958                                            i + ActivityManager.MIN_PROCESS_STATE));
14959                                pw.print("=");
14960                                TimeUtils.formatDuration(amt, pw);
14961                                if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
14962                                    pw.print("*");
14963                                }
14964                            }
14965                        }
14966                        pw.println();
14967                        if (ass.mNesting > 0) {
14968                            pw.print("    Currently active: ");
14969                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14970                            pw.println();
14971                        }
14972                    }
14973                }
14974            }
14975
14976        }
14977
14978        if (!printedAnything) {
14979            pw.println("  (nothing)");
14980        }
14981    }
14982
14983    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14984            String header, boolean needSep) {
14985        boolean printed = false;
14986        int whichAppId = -1;
14987        if (dumpPackage != null) {
14988            try {
14989                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14990                        dumpPackage, 0);
14991                whichAppId = UserHandle.getAppId(info.uid);
14992            } catch (NameNotFoundException e) {
14993                e.printStackTrace();
14994            }
14995        }
14996        for (int i=0; i<uids.size(); i++) {
14997            UidRecord uidRec = uids.valueAt(i);
14998            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14999                continue;
15000            }
15001            if (!printed) {
15002                printed = true;
15003                if (needSep) {
15004                    pw.println();
15005                }
15006                pw.print("  ");
15007                pw.println(header);
15008                needSep = true;
15009            }
15010            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
15011            pw.print(": "); pw.println(uidRec);
15012        }
15013        return printed;
15014    }
15015
15016    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15017            int opti, boolean dumpAll, String dumpPackage) {
15018        boolean needSep = false;
15019        boolean printedAnything = false;
15020        int numPers = 0;
15021
15022        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
15023
15024        if (dumpAll) {
15025            final int NP = mProcessNames.getMap().size();
15026            for (int ip=0; ip<NP; ip++) {
15027                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
15028                final int NA = procs.size();
15029                for (int ia=0; ia<NA; ia++) {
15030                    ProcessRecord r = procs.valueAt(ia);
15031                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15032                        continue;
15033                    }
15034                    if (!needSep) {
15035                        pw.println("  All known processes:");
15036                        needSep = true;
15037                        printedAnything = true;
15038                    }
15039                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
15040                        pw.print(" UID "); pw.print(procs.keyAt(ia));
15041                        pw.print(" "); pw.println(r);
15042                    r.dump(pw, "    ");
15043                    if (r.persistent) {
15044                        numPers++;
15045                    }
15046                }
15047            }
15048        }
15049
15050        if (mIsolatedProcesses.size() > 0) {
15051            boolean printed = false;
15052            for (int i=0; i<mIsolatedProcesses.size(); i++) {
15053                ProcessRecord r = mIsolatedProcesses.valueAt(i);
15054                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15055                    continue;
15056                }
15057                if (!printed) {
15058                    if (needSep) {
15059                        pw.println();
15060                    }
15061                    pw.println("  Isolated process list (sorted by uid):");
15062                    printedAnything = true;
15063                    printed = true;
15064                    needSep = true;
15065                }
15066                pw.print("    Isolated #"); pw.print(i); pw.print(": ");
15067                pw.println(r);
15068            }
15069        }
15070
15071        if (mActiveInstrumentation.size() > 0) {
15072            boolean printed = false;
15073            for (int i=0; i<mActiveInstrumentation.size(); i++) {
15074                ActiveInstrumentation ai = mActiveInstrumentation.get(i);
15075                if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
15076                        && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
15077                    continue;
15078                }
15079                if (!printed) {
15080                    if (needSep) {
15081                        pw.println();
15082                    }
15083                    pw.println("  Active instrumentation:");
15084                    printedAnything = true;
15085                    printed = true;
15086                    needSep = true;
15087                }
15088                pw.print("    Instrumentation #"); pw.print(i); pw.print(": ");
15089                pw.println(ai);
15090                ai.dump(pw, "      ");
15091            }
15092        }
15093
15094        if (mActiveUids.size() > 0) {
15095            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
15096                printedAnything = needSep = true;
15097            }
15098        }
15099        if (mValidateUids.size() > 0) {
15100            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
15101                printedAnything = needSep = true;
15102            }
15103        }
15104
15105        if (mLruProcesses.size() > 0) {
15106            if (needSep) {
15107                pw.println();
15108            }
15109            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
15110                    pw.print(" total, non-act at ");
15111                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15112                    pw.print(", non-svc at ");
15113                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15114                    pw.println("):");
15115            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
15116            needSep = true;
15117            printedAnything = true;
15118        }
15119
15120        if (dumpAll || dumpPackage != null) {
15121            synchronized (mPidsSelfLocked) {
15122                boolean printed = false;
15123                for (int i=0; i<mPidsSelfLocked.size(); i++) {
15124                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
15125                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15126                        continue;
15127                    }
15128                    if (!printed) {
15129                        if (needSep) pw.println();
15130                        needSep = true;
15131                        pw.println("  PID mappings:");
15132                        printed = true;
15133                        printedAnything = true;
15134                    }
15135                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
15136                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
15137                }
15138            }
15139        }
15140
15141        if (mForegroundProcesses.size() > 0) {
15142            synchronized (mPidsSelfLocked) {
15143                boolean printed = false;
15144                for (int i=0; i<mForegroundProcesses.size(); i++) {
15145                    ProcessRecord r = mPidsSelfLocked.get(
15146                            mForegroundProcesses.valueAt(i).pid);
15147                    if (dumpPackage != null && (r == null
15148                            || !r.pkgList.containsKey(dumpPackage))) {
15149                        continue;
15150                    }
15151                    if (!printed) {
15152                        if (needSep) pw.println();
15153                        needSep = true;
15154                        pw.println("  Foreground Processes:");
15155                        printed = true;
15156                        printedAnything = true;
15157                    }
15158                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
15159                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
15160                }
15161            }
15162        }
15163
15164        if (mPersistentStartingProcesses.size() > 0) {
15165            if (needSep) pw.println();
15166            needSep = true;
15167            printedAnything = true;
15168            pw.println("  Persisent processes that are starting:");
15169            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
15170                    "Starting Norm", "Restarting PERS", dumpPackage);
15171        }
15172
15173        if (mRemovedProcesses.size() > 0) {
15174            if (needSep) pw.println();
15175            needSep = true;
15176            printedAnything = true;
15177            pw.println("  Processes that are being removed:");
15178            dumpProcessList(pw, this, mRemovedProcesses, "    ",
15179                    "Removed Norm", "Removed PERS", dumpPackage);
15180        }
15181
15182        if (mProcessesOnHold.size() > 0) {
15183            if (needSep) pw.println();
15184            needSep = true;
15185            printedAnything = true;
15186            pw.println("  Processes that are on old until the system is ready:");
15187            dumpProcessList(pw, this, mProcessesOnHold, "    ",
15188                    "OnHold Norm", "OnHold PERS", dumpPackage);
15189        }
15190
15191        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
15192
15193        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
15194        if (needSep) {
15195            printedAnything = true;
15196        }
15197
15198        if (dumpPackage == null) {
15199            pw.println();
15200            needSep = false;
15201            mUserController.dump(pw, dumpAll);
15202        }
15203        if (mHomeProcess != null && (dumpPackage == null
15204                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
15205            if (needSep) {
15206                pw.println();
15207                needSep = false;
15208            }
15209            pw.println("  mHomeProcess: " + mHomeProcess);
15210        }
15211        if (mPreviousProcess != null && (dumpPackage == null
15212                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
15213            if (needSep) {
15214                pw.println();
15215                needSep = false;
15216            }
15217            pw.println("  mPreviousProcess: " + mPreviousProcess);
15218        }
15219        if (dumpAll) {
15220            StringBuilder sb = new StringBuilder(128);
15221            sb.append("  mPreviousProcessVisibleTime: ");
15222            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
15223            pw.println(sb);
15224        }
15225        if (mHeavyWeightProcess != null && (dumpPackage == null
15226                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
15227            if (needSep) {
15228                pw.println();
15229                needSep = false;
15230            }
15231            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
15232        }
15233        if (dumpPackage == null) {
15234            pw.println("  mGlobalConfiguration: " + getGlobalConfiguration());
15235            mStackSupervisor.dumpDisplayConfigs(pw, "  ");
15236        }
15237        if (dumpAll) {
15238            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
15239            if (mCompatModePackages.getPackages().size() > 0) {
15240                boolean printed = false;
15241                for (Map.Entry<String, Integer> entry
15242                        : mCompatModePackages.getPackages().entrySet()) {
15243                    String pkg = entry.getKey();
15244                    int mode = entry.getValue();
15245                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
15246                        continue;
15247                    }
15248                    if (!printed) {
15249                        pw.println("  mScreenCompatPackages:");
15250                        printed = true;
15251                    }
15252                    pw.print("    "); pw.print(pkg); pw.print(": ");
15253                            pw.print(mode); pw.println();
15254                }
15255            }
15256            final int NI = mUidObservers.getRegisteredCallbackCount();
15257            boolean printed = false;
15258            for (int i=0; i<NI; i++) {
15259                final UidObserverRegistration reg = (UidObserverRegistration)
15260                        mUidObservers.getRegisteredCallbackCookie(i);
15261                if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
15262                    if (!printed) {
15263                        pw.println("  mUidObservers:");
15264                        printed = true;
15265                    }
15266                    pw.print("    "); UserHandle.formatUid(pw, reg.uid);
15267                    pw.print(" "); pw.print(reg.pkg); pw.print(":");
15268                    if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
15269                        pw.print(" IDLE");
15270                    }
15271                    if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
15272                        pw.print(" ACT" );
15273                    }
15274                    if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
15275                        pw.print(" GONE");
15276                    }
15277                    if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
15278                        pw.print(" STATE");
15279                        pw.print(" (cut="); pw.print(reg.cutpoint);
15280                        pw.print(")");
15281                    }
15282                    pw.println();
15283                    if (reg.lastProcStates != null) {
15284                        final int NJ = reg.lastProcStates.size();
15285                        for (int j=0; j<NJ; j++) {
15286                            pw.print("      Last ");
15287                            UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
15288                            pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
15289                        }
15290                    }
15291                }
15292            }
15293            pw.println("  mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
15294            pw.println("  mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
15295        }
15296        if (dumpPackage == null) {
15297            pw.println("  mWakefulness="
15298                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
15299            pw.println("  mSleepTokens=" + mSleepTokens);
15300            pw.println("  mSleeping=" + mSleeping);
15301            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
15302            if (mRunningVoice != null) {
15303                pw.println("  mRunningVoice=" + mRunningVoice);
15304                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
15305            }
15306        }
15307        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
15308                || mOrigWaitForDebugger) {
15309            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
15310                    || dumpPackage.equals(mOrigDebugApp)) {
15311                if (needSep) {
15312                    pw.println();
15313                    needSep = false;
15314                }
15315                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
15316                        + " mDebugTransient=" + mDebugTransient
15317                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
15318            }
15319        }
15320        if (mCurAppTimeTracker != null) {
15321            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
15322        }
15323        if (mMemWatchProcesses.getMap().size() > 0) {
15324            pw.println("  Mem watch processes:");
15325            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
15326                    = mMemWatchProcesses.getMap();
15327            for (int i=0; i<procs.size(); i++) {
15328                final String proc = procs.keyAt(i);
15329                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
15330                for (int j=0; j<uids.size(); j++) {
15331                    if (needSep) {
15332                        pw.println();
15333                        needSep = false;
15334                    }
15335                    StringBuilder sb = new StringBuilder();
15336                    sb.append("    ").append(proc).append('/');
15337                    UserHandle.formatUid(sb, uids.keyAt(j));
15338                    Pair<Long, String> val = uids.valueAt(j);
15339                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
15340                    if (val.second != null) {
15341                        sb.append(", report to ").append(val.second);
15342                    }
15343                    pw.println(sb.toString());
15344                }
15345            }
15346            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
15347            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
15348            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
15349                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
15350        }
15351        if (mTrackAllocationApp != null) {
15352            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
15353                if (needSep) {
15354                    pw.println();
15355                    needSep = false;
15356                }
15357                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
15358            }
15359        }
15360        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
15361                || mProfileFd != null) {
15362            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
15363                if (needSep) {
15364                    pw.println();
15365                    needSep = false;
15366                }
15367                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
15368                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
15369                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
15370                        + mAutoStopProfiler + " mStreamingOutput=" + mStreamingOutput);
15371                pw.println("  mProfileType=" + mProfileType);
15372            }
15373        }
15374        if (mNativeDebuggingApp != null) {
15375            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
15376                if (needSep) {
15377                    pw.println();
15378                    needSep = false;
15379                }
15380                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
15381            }
15382        }
15383        if (dumpPackage == null) {
15384            if (mAlwaysFinishActivities) {
15385                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities);
15386            }
15387            if (mController != null) {
15388                pw.println("  mController=" + mController
15389                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
15390            }
15391            if (dumpAll) {
15392                pw.println("  Total persistent processes: " + numPers);
15393                pw.println("  mProcessesReady=" + mProcessesReady
15394                        + " mSystemReady=" + mSystemReady
15395                        + " mBooted=" + mBooted
15396                        + " mFactoryTest=" + mFactoryTest);
15397                pw.println("  mBooting=" + mBooting
15398                        + " mCallFinishBooting=" + mCallFinishBooting
15399                        + " mBootAnimationComplete=" + mBootAnimationComplete);
15400                pw.print("  mLastPowerCheckRealtime=");
15401                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
15402                        pw.println("");
15403                pw.print("  mLastPowerCheckUptime=");
15404                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
15405                        pw.println("");
15406                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
15407                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
15408                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
15409                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
15410                        + " (" + mLruProcesses.size() + " total)"
15411                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
15412                        + " mNumServiceProcs=" + mNumServiceProcs
15413                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
15414                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
15415                        + " mLastMemoryLevel=" + mLastMemoryLevel
15416                        + " mLastNumProcesses=" + mLastNumProcesses);
15417                long now = SystemClock.uptimeMillis();
15418                pw.print("  mLastIdleTime=");
15419                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
15420                        pw.print(" mLowRamSinceLastIdle=");
15421                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
15422                        pw.println();
15423            }
15424        }
15425
15426        if (!printedAnything) {
15427            pw.println("  (nothing)");
15428        }
15429    }
15430
15431    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
15432            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
15433        if (mProcessesToGc.size() > 0) {
15434            boolean printed = false;
15435            long now = SystemClock.uptimeMillis();
15436            for (int i=0; i<mProcessesToGc.size(); i++) {
15437                ProcessRecord proc = mProcessesToGc.get(i);
15438                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
15439                    continue;
15440                }
15441                if (!printed) {
15442                    if (needSep) pw.println();
15443                    needSep = true;
15444                    pw.println("  Processes that are waiting to GC:");
15445                    printed = true;
15446                }
15447                pw.print("    Process "); pw.println(proc);
15448                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
15449                        pw.print(", last gced=");
15450                        pw.print(now-proc.lastRequestedGc);
15451                        pw.print(" ms ago, last lowMem=");
15452                        pw.print(now-proc.lastLowMemory);
15453                        pw.println(" ms ago");
15454
15455            }
15456        }
15457        return needSep;
15458    }
15459
15460    void printOomLevel(PrintWriter pw, String name, int adj) {
15461        pw.print("    ");
15462        if (adj >= 0) {
15463            pw.print(' ');
15464            if (adj < 10) pw.print(' ');
15465        } else {
15466            if (adj > -10) pw.print(' ');
15467        }
15468        pw.print(adj);
15469        pw.print(": ");
15470        pw.print(name);
15471        pw.print(" (");
15472        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
15473        pw.println(")");
15474    }
15475
15476    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15477            int opti, boolean dumpAll) {
15478        boolean needSep = false;
15479
15480        if (mLruProcesses.size() > 0) {
15481            if (needSep) pw.println();
15482            needSep = true;
15483            pw.println("  OOM levels:");
15484            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
15485            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
15486            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
15487            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
15488            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
15489            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
15490            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
15491            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
15492            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
15493            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
15494            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
15495            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
15496            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
15497            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
15498
15499            if (needSep) pw.println();
15500            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
15501                    pw.print(" total, non-act at ");
15502                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15503                    pw.print(", non-svc at ");
15504                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15505                    pw.println("):");
15506            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
15507            needSep = true;
15508        }
15509
15510        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
15511
15512        pw.println();
15513        pw.println("  mHomeProcess: " + mHomeProcess);
15514        pw.println("  mPreviousProcess: " + mPreviousProcess);
15515        if (mHeavyWeightProcess != null) {
15516            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
15517        }
15518
15519        return true;
15520    }
15521
15522    /**
15523     * There are three ways to call this:
15524     *  - no provider specified: dump all the providers
15525     *  - a flattened component name that matched an existing provider was specified as the
15526     *    first arg: dump that one provider
15527     *  - the first arg isn't the flattened component name of an existing provider:
15528     *    dump all providers whose component contains the first arg as a substring
15529     */
15530    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15531            int opti, boolean dumpAll) {
15532        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
15533    }
15534
15535    static class ItemMatcher {
15536        ArrayList<ComponentName> components;
15537        ArrayList<String> strings;
15538        ArrayList<Integer> objects;
15539        boolean all;
15540
15541        ItemMatcher() {
15542            all = true;
15543        }
15544
15545        void build(String name) {
15546            ComponentName componentName = ComponentName.unflattenFromString(name);
15547            if (componentName != null) {
15548                if (components == null) {
15549                    components = new ArrayList<ComponentName>();
15550                }
15551                components.add(componentName);
15552                all = false;
15553            } else {
15554                int objectId = 0;
15555                // Not a '/' separated full component name; maybe an object ID?
15556                try {
15557                    objectId = Integer.parseInt(name, 16);
15558                    if (objects == null) {
15559                        objects = new ArrayList<Integer>();
15560                    }
15561                    objects.add(objectId);
15562                    all = false;
15563                } catch (RuntimeException e) {
15564                    // Not an integer; just do string match.
15565                    if (strings == null) {
15566                        strings = new ArrayList<String>();
15567                    }
15568                    strings.add(name);
15569                    all = false;
15570                }
15571            }
15572        }
15573
15574        int build(String[] args, int opti) {
15575            for (; opti<args.length; opti++) {
15576                String name = args[opti];
15577                if ("--".equals(name)) {
15578                    return opti+1;
15579                }
15580                build(name);
15581            }
15582            return opti;
15583        }
15584
15585        boolean match(Object object, ComponentName comp) {
15586            if (all) {
15587                return true;
15588            }
15589            if (components != null) {
15590                for (int i=0; i<components.size(); i++) {
15591                    if (components.get(i).equals(comp)) {
15592                        return true;
15593                    }
15594                }
15595            }
15596            if (objects != null) {
15597                for (int i=0; i<objects.size(); i++) {
15598                    if (System.identityHashCode(object) == objects.get(i)) {
15599                        return true;
15600                    }
15601                }
15602            }
15603            if (strings != null) {
15604                String flat = comp.flattenToString();
15605                for (int i=0; i<strings.size(); i++) {
15606                    if (flat.contains(strings.get(i))) {
15607                        return true;
15608                    }
15609                }
15610            }
15611            return false;
15612        }
15613    }
15614
15615    /**
15616     * There are three things that cmd can be:
15617     *  - a flattened component name that matches an existing activity
15618     *  - the cmd arg isn't the flattened component name of an existing activity:
15619     *    dump all activity whose component contains the cmd as a substring
15620     *  - A hex number of the ActivityRecord object instance.
15621     *
15622     *  @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
15623     *  @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
15624     */
15625    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15626            int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
15627        ArrayList<ActivityRecord> activities;
15628
15629        synchronized (this) {
15630            activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
15631                    dumpFocusedStackOnly);
15632        }
15633
15634        if (activities.size() <= 0) {
15635            return false;
15636        }
15637
15638        String[] newArgs = new String[args.length - opti];
15639        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15640
15641        TaskRecord lastTask = null;
15642        boolean needSep = false;
15643        for (int i=activities.size()-1; i>=0; i--) {
15644            ActivityRecord r = activities.get(i);
15645            if (needSep) {
15646                pw.println();
15647            }
15648            needSep = true;
15649            synchronized (this) {
15650                if (lastTask != r.task) {
15651                    lastTask = r.task;
15652                    pw.print("TASK "); pw.print(lastTask.affinity);
15653                            pw.print(" id="); pw.print(lastTask.taskId);
15654                            pw.print(" userId="); pw.println(lastTask.userId);
15655                    if (dumpAll) {
15656                        lastTask.dump(pw, "  ");
15657                    }
15658                }
15659            }
15660            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
15661        }
15662        return true;
15663    }
15664
15665    /**
15666     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
15667     * there is a thread associated with the activity.
15668     */
15669    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
15670            final ActivityRecord r, String[] args, boolean dumpAll) {
15671        String innerPrefix = prefix + "  ";
15672        synchronized (this) {
15673            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
15674                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
15675                    pw.print(" pid=");
15676                    if (r.app != null) pw.println(r.app.pid);
15677                    else pw.println("(not running)");
15678            if (dumpAll) {
15679                r.dump(pw, innerPrefix);
15680            }
15681        }
15682        if (r.app != null && r.app.thread != null) {
15683            // flush anything that is already in the PrintWriter since the thread is going
15684            // to write to the file descriptor directly
15685            pw.flush();
15686            try {
15687                TransferPipe tp = new TransferPipe();
15688                try {
15689                    r.app.thread.dumpActivity(tp.getWriteFd(),
15690                            r.appToken, innerPrefix, args);
15691                    tp.go(fd);
15692                } finally {
15693                    tp.kill();
15694                }
15695            } catch (IOException e) {
15696                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
15697            } catch (RemoteException e) {
15698                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
15699            }
15700        }
15701    }
15702
15703    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15704            int opti, boolean dumpAll, String dumpPackage) {
15705        boolean needSep = false;
15706        boolean onlyHistory = false;
15707        boolean printedAnything = false;
15708
15709        if ("history".equals(dumpPackage)) {
15710            if (opti < args.length && "-s".equals(args[opti])) {
15711                dumpAll = false;
15712            }
15713            onlyHistory = true;
15714            dumpPackage = null;
15715        }
15716
15717        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
15718        if (!onlyHistory && dumpAll) {
15719            if (mRegisteredReceivers.size() > 0) {
15720                boolean printed = false;
15721                Iterator it = mRegisteredReceivers.values().iterator();
15722                while (it.hasNext()) {
15723                    ReceiverList r = (ReceiverList)it.next();
15724                    if (dumpPackage != null && (r.app == null ||
15725                            !dumpPackage.equals(r.app.info.packageName))) {
15726                        continue;
15727                    }
15728                    if (!printed) {
15729                        pw.println("  Registered Receivers:");
15730                        needSep = true;
15731                        printed = true;
15732                        printedAnything = true;
15733                    }
15734                    pw.print("  * "); pw.println(r);
15735                    r.dump(pw, "    ");
15736                }
15737            }
15738
15739            if (mReceiverResolver.dump(pw, needSep ?
15740                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
15741                    "    ", dumpPackage, false, false)) {
15742                needSep = true;
15743                printedAnything = true;
15744            }
15745        }
15746
15747        for (BroadcastQueue q : mBroadcastQueues) {
15748            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
15749            printedAnything |= needSep;
15750        }
15751
15752        needSep = true;
15753
15754        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15755            for (int user=0; user<mStickyBroadcasts.size(); user++) {
15756                if (needSep) {
15757                    pw.println();
15758                }
15759                needSep = true;
15760                printedAnything = true;
15761                pw.print("  Sticky broadcasts for user ");
15762                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15763                StringBuilder sb = new StringBuilder(128);
15764                for (Map.Entry<String, ArrayList<Intent>> ent
15765                        : mStickyBroadcasts.valueAt(user).entrySet()) {
15766                    pw.print("  * Sticky action "); pw.print(ent.getKey());
15767                    if (dumpAll) {
15768                        pw.println(":");
15769                        ArrayList<Intent> intents = ent.getValue();
15770                        final int N = intents.size();
15771                        for (int i=0; i<N; i++) {
15772                            sb.setLength(0);
15773                            sb.append("    Intent: ");
15774                            intents.get(i).toShortString(sb, false, true, false, false);
15775                            pw.println(sb.toString());
15776                            Bundle bundle = intents.get(i).getExtras();
15777                            if (bundle != null) {
15778                                pw.print("      ");
15779                                pw.println(bundle.toString());
15780                            }
15781                        }
15782                    } else {
15783                        pw.println("");
15784                    }
15785                }
15786            }
15787        }
15788
15789        if (!onlyHistory && dumpAll) {
15790            pw.println();
15791            for (BroadcastQueue queue : mBroadcastQueues) {
15792                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
15793                        + queue.mBroadcastsScheduled);
15794            }
15795            pw.println("  mHandler:");
15796            mHandler.dump(new PrintWriterPrinter(pw), "    ");
15797            needSep = true;
15798            printedAnything = true;
15799        }
15800
15801        if (!printedAnything) {
15802            pw.println("  (nothing)");
15803        }
15804    }
15805
15806    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15807            int opti, boolean dumpAll, String dumpPackage) {
15808        if (mCurBroadcastStats == null) {
15809            return;
15810        }
15811
15812        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15813        final long now = SystemClock.elapsedRealtime();
15814        if (mLastBroadcastStats != null) {
15815            pw.print("  Last stats (from ");
15816            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15817            pw.print(" to ");
15818            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15819            pw.print(", ");
15820            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15821                    - mLastBroadcastStats.mStartUptime, pw);
15822            pw.println(" uptime):");
15823            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15824                pw.println("    (nothing)");
15825            }
15826            pw.println();
15827        }
15828        pw.print("  Current stats (from ");
15829        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15830        pw.print(" to now, ");
15831        TimeUtils.formatDuration(SystemClock.uptimeMillis()
15832                - mCurBroadcastStats.mStartUptime, pw);
15833        pw.println(" uptime):");
15834        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15835            pw.println("    (nothing)");
15836        }
15837    }
15838
15839    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15840            int opti, boolean fullCheckin, String dumpPackage) {
15841        if (mCurBroadcastStats == null) {
15842            return;
15843        }
15844
15845        if (mLastBroadcastStats != null) {
15846            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15847            if (fullCheckin) {
15848                mLastBroadcastStats = null;
15849                return;
15850            }
15851        }
15852        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15853        if (fullCheckin) {
15854            mCurBroadcastStats = null;
15855        }
15856    }
15857
15858    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15859            int opti, boolean dumpAll, String dumpPackage) {
15860        boolean needSep;
15861        boolean printedAnything = false;
15862
15863        ItemMatcher matcher = new ItemMatcher();
15864        matcher.build(args, opti);
15865
15866        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15867
15868        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15869        printedAnything |= needSep;
15870
15871        if (mLaunchingProviders.size() > 0) {
15872            boolean printed = false;
15873            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15874                ContentProviderRecord r = mLaunchingProviders.get(i);
15875                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15876                    continue;
15877                }
15878                if (!printed) {
15879                    if (needSep) pw.println();
15880                    needSep = true;
15881                    pw.println("  Launching content providers:");
15882                    printed = true;
15883                    printedAnything = true;
15884                }
15885                pw.print("  Launching #"); pw.print(i); pw.print(": ");
15886                        pw.println(r);
15887            }
15888        }
15889
15890        if (!printedAnything) {
15891            pw.println("  (nothing)");
15892        }
15893    }
15894
15895    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15896            int opti, boolean dumpAll, String dumpPackage) {
15897        boolean needSep = false;
15898        boolean printedAnything = false;
15899
15900        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15901
15902        if (mGrantedUriPermissions.size() > 0) {
15903            boolean printed = false;
15904            int dumpUid = -2;
15905            if (dumpPackage != null) {
15906                try {
15907                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15908                            MATCH_ANY_USER, 0);
15909                } catch (NameNotFoundException e) {
15910                    dumpUid = -1;
15911                }
15912            }
15913            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15914                int uid = mGrantedUriPermissions.keyAt(i);
15915                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15916                    continue;
15917                }
15918                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15919                if (!printed) {
15920                    if (needSep) pw.println();
15921                    needSep = true;
15922                    pw.println("  Granted Uri Permissions:");
15923                    printed = true;
15924                    printedAnything = true;
15925                }
15926                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15927                for (UriPermission perm : perms.values()) {
15928                    pw.print("    "); pw.println(perm);
15929                    if (dumpAll) {
15930                        perm.dump(pw, "      ");
15931                    }
15932                }
15933            }
15934        }
15935
15936        if (!printedAnything) {
15937            pw.println("  (nothing)");
15938        }
15939    }
15940
15941    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15942            int opti, boolean dumpAll, String dumpPackage) {
15943        boolean printed = false;
15944
15945        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15946
15947        if (mIntentSenderRecords.size() > 0) {
15948            Iterator<WeakReference<PendingIntentRecord>> it
15949                    = mIntentSenderRecords.values().iterator();
15950            while (it.hasNext()) {
15951                WeakReference<PendingIntentRecord> ref = it.next();
15952                PendingIntentRecord rec = ref != null ? ref.get(): null;
15953                if (dumpPackage != null && (rec == null
15954                        || !dumpPackage.equals(rec.key.packageName))) {
15955                    continue;
15956                }
15957                printed = true;
15958                if (rec != null) {
15959                    pw.print("  * "); pw.println(rec);
15960                    if (dumpAll) {
15961                        rec.dump(pw, "    ");
15962                    }
15963                } else {
15964                    pw.print("  * "); pw.println(ref);
15965                }
15966            }
15967        }
15968
15969        if (!printed) {
15970            pw.println("  (nothing)");
15971        }
15972    }
15973
15974    private static final int dumpProcessList(PrintWriter pw,
15975            ActivityManagerService service, List list,
15976            String prefix, String normalLabel, String persistentLabel,
15977            String dumpPackage) {
15978        int numPers = 0;
15979        final int N = list.size()-1;
15980        for (int i=N; i>=0; i--) {
15981            ProcessRecord r = (ProcessRecord)list.get(i);
15982            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15983                continue;
15984            }
15985            pw.println(String.format("%s%s #%2d: %s",
15986                    prefix, (r.persistent ? persistentLabel : normalLabel),
15987                    i, r.toString()));
15988            if (r.persistent) {
15989                numPers++;
15990            }
15991        }
15992        return numPers;
15993    }
15994
15995    private static final boolean dumpProcessOomList(PrintWriter pw,
15996            ActivityManagerService service, List<ProcessRecord> origList,
15997            String prefix, String normalLabel, String persistentLabel,
15998            boolean inclDetails, String dumpPackage) {
15999
16000        ArrayList<Pair<ProcessRecord, Integer>> list
16001                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
16002        for (int i=0; i<origList.size(); i++) {
16003            ProcessRecord r = origList.get(i);
16004            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16005                continue;
16006            }
16007            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
16008        }
16009
16010        if (list.size() <= 0) {
16011            return false;
16012        }
16013
16014        Comparator<Pair<ProcessRecord, Integer>> comparator
16015                = new Comparator<Pair<ProcessRecord, Integer>>() {
16016            @Override
16017            public int compare(Pair<ProcessRecord, Integer> object1,
16018                    Pair<ProcessRecord, Integer> object2) {
16019                if (object1.first.setAdj != object2.first.setAdj) {
16020                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
16021                }
16022                if (object1.first.setProcState != object2.first.setProcState) {
16023                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
16024                }
16025                if (object1.second.intValue() != object2.second.intValue()) {
16026                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
16027                }
16028                return 0;
16029            }
16030        };
16031
16032        Collections.sort(list, comparator);
16033
16034        final long curRealtime = SystemClock.elapsedRealtime();
16035        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
16036        final long curUptime = SystemClock.uptimeMillis();
16037        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
16038
16039        for (int i=list.size()-1; i>=0; i--) {
16040            ProcessRecord r = list.get(i).first;
16041            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
16042            char schedGroup;
16043            switch (r.setSchedGroup) {
16044                case ProcessList.SCHED_GROUP_BACKGROUND:
16045                    schedGroup = 'B';
16046                    break;
16047                case ProcessList.SCHED_GROUP_DEFAULT:
16048                    schedGroup = 'F';
16049                    break;
16050                case ProcessList.SCHED_GROUP_TOP_APP:
16051                    schedGroup = 'T';
16052                    break;
16053                default:
16054                    schedGroup = '?';
16055                    break;
16056            }
16057            char foreground;
16058            if (r.foregroundActivities) {
16059                foreground = 'A';
16060            } else if (r.foregroundServices) {
16061                foreground = 'S';
16062            } else {
16063                foreground = ' ';
16064            }
16065            String procState = ProcessList.makeProcStateString(r.curProcState);
16066            pw.print(prefix);
16067            pw.print(r.persistent ? persistentLabel : normalLabel);
16068            pw.print(" #");
16069            int num = (origList.size()-1)-list.get(i).second;
16070            if (num < 10) pw.print(' ');
16071            pw.print(num);
16072            pw.print(": ");
16073            pw.print(oomAdj);
16074            pw.print(' ');
16075            pw.print(schedGroup);
16076            pw.print('/');
16077            pw.print(foreground);
16078            pw.print('/');
16079            pw.print(procState);
16080            pw.print(" trm:");
16081            if (r.trimMemoryLevel < 10) pw.print(' ');
16082            pw.print(r.trimMemoryLevel);
16083            pw.print(' ');
16084            pw.print(r.toShortString());
16085            pw.print(" (");
16086            pw.print(r.adjType);
16087            pw.println(')');
16088            if (r.adjSource != null || r.adjTarget != null) {
16089                pw.print(prefix);
16090                pw.print("    ");
16091                if (r.adjTarget instanceof ComponentName) {
16092                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
16093                } else if (r.adjTarget != null) {
16094                    pw.print(r.adjTarget.toString());
16095                } else {
16096                    pw.print("{null}");
16097                }
16098                pw.print("<=");
16099                if (r.adjSource instanceof ProcessRecord) {
16100                    pw.print("Proc{");
16101                    pw.print(((ProcessRecord)r.adjSource).toShortString());
16102                    pw.println("}");
16103                } else if (r.adjSource != null) {
16104                    pw.println(r.adjSource.toString());
16105                } else {
16106                    pw.println("{null}");
16107                }
16108            }
16109            if (inclDetails) {
16110                pw.print(prefix);
16111                pw.print("    ");
16112                pw.print("oom: max="); pw.print(r.maxAdj);
16113                pw.print(" curRaw="); pw.print(r.curRawAdj);
16114                pw.print(" setRaw="); pw.print(r.setRawAdj);
16115                pw.print(" cur="); pw.print(r.curAdj);
16116                pw.print(" set="); pw.println(r.setAdj);
16117                pw.print(prefix);
16118                pw.print("    ");
16119                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
16120                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
16121                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
16122                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
16123                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
16124                pw.println();
16125                pw.print(prefix);
16126                pw.print("    ");
16127                pw.print("cached="); pw.print(r.cached);
16128                pw.print(" empty="); pw.print(r.empty);
16129                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
16130
16131                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
16132                    if (r.lastWakeTime != 0) {
16133                        long wtime;
16134                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
16135                        synchronized (stats) {
16136                            wtime = stats.getProcessWakeTime(r.info.uid,
16137                                    r.pid, curRealtime);
16138                        }
16139                        long timeUsed = wtime - r.lastWakeTime;
16140                        pw.print(prefix);
16141                        pw.print("    ");
16142                        pw.print("keep awake over ");
16143                        TimeUtils.formatDuration(realtimeSince, pw);
16144                        pw.print(" used ");
16145                        TimeUtils.formatDuration(timeUsed, pw);
16146                        pw.print(" (");
16147                        pw.print((timeUsed*100)/realtimeSince);
16148                        pw.println("%)");
16149                    }
16150                    if (r.lastCpuTime != 0) {
16151                        long timeUsed = r.curCpuTime - r.lastCpuTime;
16152                        pw.print(prefix);
16153                        pw.print("    ");
16154                        pw.print("run cpu over ");
16155                        TimeUtils.formatDuration(uptimeSince, pw);
16156                        pw.print(" used ");
16157                        TimeUtils.formatDuration(timeUsed, pw);
16158                        pw.print(" (");
16159                        pw.print((timeUsed*100)/uptimeSince);
16160                        pw.println("%)");
16161                    }
16162                }
16163            }
16164        }
16165        return true;
16166    }
16167
16168    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
16169            String[] args) {
16170        ArrayList<ProcessRecord> procs;
16171        synchronized (this) {
16172            if (args != null && args.length > start
16173                    && args[start].charAt(0) != '-') {
16174                procs = new ArrayList<ProcessRecord>();
16175                int pid = -1;
16176                try {
16177                    pid = Integer.parseInt(args[start]);
16178                } catch (NumberFormatException e) {
16179                }
16180                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16181                    ProcessRecord proc = mLruProcesses.get(i);
16182                    if (proc.pid == pid) {
16183                        procs.add(proc);
16184                    } else if (allPkgs && proc.pkgList != null
16185                            && proc.pkgList.containsKey(args[start])) {
16186                        procs.add(proc);
16187                    } else if (proc.processName.equals(args[start])) {
16188                        procs.add(proc);
16189                    }
16190                }
16191                if (procs.size() <= 0) {
16192                    return null;
16193                }
16194            } else {
16195                procs = new ArrayList<ProcessRecord>(mLruProcesses);
16196            }
16197        }
16198        return procs;
16199    }
16200
16201    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
16202            PrintWriter pw, String[] args) {
16203        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16204        if (procs == null) {
16205            pw.println("No process found for: " + args[0]);
16206            return;
16207        }
16208
16209        long uptime = SystemClock.uptimeMillis();
16210        long realtime = SystemClock.elapsedRealtime();
16211        pw.println("Applications Graphics Acceleration Info:");
16212        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16213
16214        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16215            ProcessRecord r = procs.get(i);
16216            if (r.thread != null) {
16217                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
16218                pw.flush();
16219                try {
16220                    TransferPipe tp = new TransferPipe();
16221                    try {
16222                        r.thread.dumpGfxInfo(tp.getWriteFd(), args);
16223                        tp.go(fd);
16224                    } finally {
16225                        tp.kill();
16226                    }
16227                } catch (IOException e) {
16228                    pw.println("Failure while dumping the app: " + r);
16229                    pw.flush();
16230                } catch (RemoteException e) {
16231                    pw.println("Got a RemoteException while dumping the app " + r);
16232                    pw.flush();
16233                }
16234            }
16235        }
16236    }
16237
16238    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
16239        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16240        if (procs == null) {
16241            pw.println("No process found for: " + args[0]);
16242            return;
16243        }
16244
16245        pw.println("Applications Database Info:");
16246
16247        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16248            ProcessRecord r = procs.get(i);
16249            if (r.thread != null) {
16250                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
16251                pw.flush();
16252                try {
16253                    TransferPipe tp = new TransferPipe();
16254                    try {
16255                        r.thread.dumpDbInfo(tp.getWriteFd(), args);
16256                        tp.go(fd);
16257                    } finally {
16258                        tp.kill();
16259                    }
16260                } catch (IOException e) {
16261                    pw.println("Failure while dumping the app: " + r);
16262                    pw.flush();
16263                } catch (RemoteException e) {
16264                    pw.println("Got a RemoteException while dumping the app " + r);
16265                    pw.flush();
16266                }
16267            }
16268        }
16269    }
16270
16271    final static class MemItem {
16272        final boolean isProc;
16273        final String label;
16274        final String shortLabel;
16275        final long pss;
16276        final long swapPss;
16277        final int id;
16278        final boolean hasActivities;
16279        ArrayList<MemItem> subitems;
16280
16281        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
16282                boolean _hasActivities) {
16283            isProc = true;
16284            label = _label;
16285            shortLabel = _shortLabel;
16286            pss = _pss;
16287            swapPss = _swapPss;
16288            id = _id;
16289            hasActivities = _hasActivities;
16290        }
16291
16292        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
16293            isProc = false;
16294            label = _label;
16295            shortLabel = _shortLabel;
16296            pss = _pss;
16297            swapPss = _swapPss;
16298            id = _id;
16299            hasActivities = false;
16300        }
16301    }
16302
16303    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
16304            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
16305        if (sort && !isCompact) {
16306            Collections.sort(items, new Comparator<MemItem>() {
16307                @Override
16308                public int compare(MemItem lhs, MemItem rhs) {
16309                    if (lhs.pss < rhs.pss) {
16310                        return 1;
16311                    } else if (lhs.pss > rhs.pss) {
16312                        return -1;
16313                    }
16314                    return 0;
16315                }
16316            });
16317        }
16318
16319        for (int i=0; i<items.size(); i++) {
16320            MemItem mi = items.get(i);
16321            if (!isCompact) {
16322                if (dumpSwapPss) {
16323                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
16324                            mi.label, stringifyKBSize(mi.swapPss));
16325                } else {
16326                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
16327                }
16328            } else if (mi.isProc) {
16329                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
16330                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
16331                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
16332                pw.println(mi.hasActivities ? ",a" : ",e");
16333            } else {
16334                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
16335                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
16336            }
16337            if (mi.subitems != null) {
16338                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
16339                        true, isCompact, dumpSwapPss);
16340            }
16341        }
16342    }
16343
16344    // These are in KB.
16345    static final long[] DUMP_MEM_BUCKETS = new long[] {
16346        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
16347        120*1024, 160*1024, 200*1024,
16348        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
16349        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
16350    };
16351
16352    static final void appendMemBucket(StringBuilder out, long memKB, String label,
16353            boolean stackLike) {
16354        int start = label.lastIndexOf('.');
16355        if (start >= 0) start++;
16356        else start = 0;
16357        int end = label.length();
16358        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
16359            if (DUMP_MEM_BUCKETS[i] >= memKB) {
16360                long bucket = DUMP_MEM_BUCKETS[i]/1024;
16361                out.append(bucket);
16362                out.append(stackLike ? "MB." : "MB ");
16363                out.append(label, start, end);
16364                return;
16365            }
16366        }
16367        out.append(memKB/1024);
16368        out.append(stackLike ? "MB." : "MB ");
16369        out.append(label, start, end);
16370    }
16371
16372    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
16373            ProcessList.NATIVE_ADJ,
16374            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
16375            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
16376            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
16377            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
16378            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
16379            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
16380    };
16381    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
16382            "Native",
16383            "System", "Persistent", "Persistent Service", "Foreground",
16384            "Visible", "Perceptible",
16385            "Heavy Weight", "Backup",
16386            "A Services", "Home",
16387            "Previous", "B Services", "Cached"
16388    };
16389    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
16390            "native",
16391            "sys", "pers", "persvc", "fore",
16392            "vis", "percept",
16393            "heavy", "backup",
16394            "servicea", "home",
16395            "prev", "serviceb", "cached"
16396    };
16397
16398    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
16399            long realtime, boolean isCheckinRequest, boolean isCompact) {
16400        if (isCompact) {
16401            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
16402        }
16403        if (isCheckinRequest || isCompact) {
16404            // short checkin version
16405            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
16406        } else {
16407            pw.println("Applications Memory Usage (in Kilobytes):");
16408            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16409        }
16410    }
16411
16412    private static final int KSM_SHARED = 0;
16413    private static final int KSM_SHARING = 1;
16414    private static final int KSM_UNSHARED = 2;
16415    private static final int KSM_VOLATILE = 3;
16416
16417    private final long[] getKsmInfo() {
16418        long[] longOut = new long[4];
16419        final int[] SINGLE_LONG_FORMAT = new int[] {
16420            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
16421        };
16422        long[] longTmp = new long[1];
16423        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
16424                SINGLE_LONG_FORMAT, null, longTmp, null);
16425        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16426        longTmp[0] = 0;
16427        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
16428                SINGLE_LONG_FORMAT, null, longTmp, null);
16429        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16430        longTmp[0] = 0;
16431        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
16432                SINGLE_LONG_FORMAT, null, longTmp, null);
16433        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16434        longTmp[0] = 0;
16435        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
16436                SINGLE_LONG_FORMAT, null, longTmp, null);
16437        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16438        return longOut;
16439    }
16440
16441    private static String stringifySize(long size, int order) {
16442        Locale locale = Locale.US;
16443        switch (order) {
16444            case 1:
16445                return String.format(locale, "%,13d", size);
16446            case 1024:
16447                return String.format(locale, "%,9dK", size / 1024);
16448            case 1024 * 1024:
16449                return String.format(locale, "%,5dM", size / 1024 / 1024);
16450            case 1024 * 1024 * 1024:
16451                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
16452            default:
16453                throw new IllegalArgumentException("Invalid size order");
16454        }
16455    }
16456
16457    private static String stringifyKBSize(long size) {
16458        return stringifySize(size * 1024, 1024);
16459    }
16460
16461    // Update this version number in case you change the 'compact' format
16462    private static final int MEMINFO_COMPACT_VERSION = 1;
16463
16464    final void dumpApplicationMemoryUsage(FileDescriptor fd,
16465            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
16466        boolean dumpDetails = false;
16467        boolean dumpFullDetails = false;
16468        boolean dumpDalvik = false;
16469        boolean dumpSummaryOnly = false;
16470        boolean dumpUnreachable = false;
16471        boolean oomOnly = false;
16472        boolean isCompact = false;
16473        boolean localOnly = false;
16474        boolean packages = false;
16475        boolean isCheckinRequest = false;
16476        boolean dumpSwapPss = false;
16477
16478        int opti = 0;
16479        while (opti < args.length) {
16480            String opt = args[opti];
16481            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
16482                break;
16483            }
16484            opti++;
16485            if ("-a".equals(opt)) {
16486                dumpDetails = true;
16487                dumpFullDetails = true;
16488                dumpDalvik = true;
16489                dumpSwapPss = true;
16490            } else if ("-d".equals(opt)) {
16491                dumpDalvik = true;
16492            } else if ("-c".equals(opt)) {
16493                isCompact = true;
16494            } else if ("-s".equals(opt)) {
16495                dumpDetails = true;
16496                dumpSummaryOnly = true;
16497            } else if ("-S".equals(opt)) {
16498                dumpSwapPss = true;
16499            } else if ("--unreachable".equals(opt)) {
16500                dumpUnreachable = true;
16501            } else if ("--oom".equals(opt)) {
16502                oomOnly = true;
16503            } else if ("--local".equals(opt)) {
16504                localOnly = true;
16505            } else if ("--package".equals(opt)) {
16506                packages = true;
16507            } else if ("--checkin".equals(opt)) {
16508                isCheckinRequest = true;
16509
16510            } else if ("-h".equals(opt)) {
16511                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
16512                pw.println("  -a: include all available information for each process.");
16513                pw.println("  -d: include dalvik details.");
16514                pw.println("  -c: dump in a compact machine-parseable representation.");
16515                pw.println("  -s: dump only summary of application memory usage.");
16516                pw.println("  -S: dump also SwapPss.");
16517                pw.println("  --oom: only show processes organized by oom adj.");
16518                pw.println("  --local: only collect details locally, don't call process.");
16519                pw.println("  --package: interpret process arg as package, dumping all");
16520                pw.println("             processes that have loaded that package.");
16521                pw.println("  --checkin: dump data for a checkin");
16522                pw.println("If [process] is specified it can be the name or ");
16523                pw.println("pid of a specific process to dump.");
16524                return;
16525            } else {
16526                pw.println("Unknown argument: " + opt + "; use -h for help");
16527            }
16528        }
16529
16530        long uptime = SystemClock.uptimeMillis();
16531        long realtime = SystemClock.elapsedRealtime();
16532        final long[] tmpLong = new long[1];
16533
16534        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
16535        if (procs == null) {
16536            // No Java processes.  Maybe they want to print a native process.
16537            if (args != null && args.length > opti
16538                    && args[opti].charAt(0) != '-') {
16539                ArrayList<ProcessCpuTracker.Stats> nativeProcs
16540                        = new ArrayList<ProcessCpuTracker.Stats>();
16541                updateCpuStatsNow();
16542                int findPid = -1;
16543                try {
16544                    findPid = Integer.parseInt(args[opti]);
16545                } catch (NumberFormatException e) {
16546                }
16547                synchronized (mProcessCpuTracker) {
16548                    final int N = mProcessCpuTracker.countStats();
16549                    for (int i=0; i<N; i++) {
16550                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16551                        if (st.pid == findPid || (st.baseName != null
16552                                && st.baseName.equals(args[opti]))) {
16553                            nativeProcs.add(st);
16554                        }
16555                    }
16556                }
16557                if (nativeProcs.size() > 0) {
16558                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
16559                            isCompact);
16560                    Debug.MemoryInfo mi = null;
16561                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
16562                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
16563                        final int pid = r.pid;
16564                        if (!isCheckinRequest && dumpDetails) {
16565                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
16566                        }
16567                        if (mi == null) {
16568                            mi = new Debug.MemoryInfo();
16569                        }
16570                        if (dumpDetails || (!brief && !oomOnly)) {
16571                            Debug.getMemoryInfo(pid, mi);
16572                        } else {
16573                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16574                            mi.dalvikPrivateDirty = (int)tmpLong[0];
16575                        }
16576                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16577                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
16578                        if (isCheckinRequest) {
16579                            pw.println();
16580                        }
16581                    }
16582                    return;
16583                }
16584            }
16585            pw.println("No process found for: " + args[opti]);
16586            return;
16587        }
16588
16589        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
16590            dumpDetails = true;
16591        }
16592
16593        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
16594
16595        String[] innerArgs = new String[args.length-opti];
16596        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
16597
16598        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
16599        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
16600        long nativePss = 0;
16601        long nativeSwapPss = 0;
16602        long dalvikPss = 0;
16603        long dalvikSwapPss = 0;
16604        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16605                EmptyArray.LONG;
16606        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16607                EmptyArray.LONG;
16608        long otherPss = 0;
16609        long otherSwapPss = 0;
16610        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16611        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16612
16613        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16614        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16615        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
16616                new ArrayList[DUMP_MEM_OOM_LABEL.length];
16617
16618        long totalPss = 0;
16619        long totalSwapPss = 0;
16620        long cachedPss = 0;
16621        long cachedSwapPss = 0;
16622        boolean hasSwapPss = false;
16623
16624        Debug.MemoryInfo mi = null;
16625        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16626            final ProcessRecord r = procs.get(i);
16627            final IApplicationThread thread;
16628            final int pid;
16629            final int oomAdj;
16630            final boolean hasActivities;
16631            synchronized (this) {
16632                thread = r.thread;
16633                pid = r.pid;
16634                oomAdj = r.getSetAdjWithServices();
16635                hasActivities = r.activities.size() > 0;
16636            }
16637            if (thread != null) {
16638                if (!isCheckinRequest && dumpDetails) {
16639                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
16640                }
16641                if (mi == null) {
16642                    mi = new Debug.MemoryInfo();
16643                }
16644                if (dumpDetails || (!brief && !oomOnly)) {
16645                    Debug.getMemoryInfo(pid, mi);
16646                    hasSwapPss = mi.hasSwappedOutPss;
16647                } else {
16648                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16649                    mi.dalvikPrivateDirty = (int)tmpLong[0];
16650                }
16651                if (dumpDetails) {
16652                    if (localOnly) {
16653                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16654                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
16655                        if (isCheckinRequest) {
16656                            pw.println();
16657                        }
16658                    } else {
16659                        pw.flush();
16660                        try {
16661                            TransferPipe tp = new TransferPipe();
16662                            try {
16663                                thread.dumpMemInfo(tp.getWriteFd(),
16664                                        mi, isCheckinRequest, dumpFullDetails,
16665                                        dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
16666                                tp.go(fd);
16667                            } finally {
16668                                tp.kill();
16669                            }
16670                        } catch (IOException e) {
16671                            if (!isCheckinRequest) {
16672                                pw.println("Got IoException!");
16673                                pw.flush();
16674                            }
16675                        } catch (RemoteException e) {
16676                            if (!isCheckinRequest) {
16677                                pw.println("Got RemoteException!");
16678                                pw.flush();
16679                            }
16680                        }
16681                    }
16682                }
16683
16684                final long myTotalPss = mi.getTotalPss();
16685                final long myTotalUss = mi.getTotalUss();
16686                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16687
16688                synchronized (this) {
16689                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
16690                        // Record this for posterity if the process has been stable.
16691                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
16692                    }
16693                }
16694
16695                if (!isCheckinRequest && mi != null) {
16696                    totalPss += myTotalPss;
16697                    totalSwapPss += myTotalSwapPss;
16698                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
16699                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
16700                            myTotalSwapPss, pid, hasActivities);
16701                    procMems.add(pssItem);
16702                    procMemsMap.put(pid, pssItem);
16703
16704                    nativePss += mi.nativePss;
16705                    nativeSwapPss += mi.nativeSwappedOutPss;
16706                    dalvikPss += mi.dalvikPss;
16707                    dalvikSwapPss += mi.dalvikSwappedOutPss;
16708                    for (int j=0; j<dalvikSubitemPss.length; j++) {
16709                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16710                        dalvikSubitemSwapPss[j] +=
16711                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16712                    }
16713                    otherPss += mi.otherPss;
16714                    otherSwapPss += mi.otherSwappedOutPss;
16715                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16716                        long mem = mi.getOtherPss(j);
16717                        miscPss[j] += mem;
16718                        otherPss -= mem;
16719                        mem = mi.getOtherSwappedOutPss(j);
16720                        miscSwapPss[j] += mem;
16721                        otherSwapPss -= mem;
16722                    }
16723
16724                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16725                        cachedPss += myTotalPss;
16726                        cachedSwapPss += myTotalSwapPss;
16727                    }
16728
16729                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
16730                        if (oomIndex == (oomPss.length - 1)
16731                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
16732                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
16733                            oomPss[oomIndex] += myTotalPss;
16734                            oomSwapPss[oomIndex] += myTotalSwapPss;
16735                            if (oomProcs[oomIndex] == null) {
16736                                oomProcs[oomIndex] = new ArrayList<MemItem>();
16737                            }
16738                            oomProcs[oomIndex].add(pssItem);
16739                            break;
16740                        }
16741                    }
16742                }
16743            }
16744        }
16745
16746        long nativeProcTotalPss = 0;
16747
16748        if (!isCheckinRequest && procs.size() > 1 && !packages) {
16749            // If we are showing aggregations, also look for native processes to
16750            // include so that our aggregations are more accurate.
16751            updateCpuStatsNow();
16752            mi = null;
16753            synchronized (mProcessCpuTracker) {
16754                final int N = mProcessCpuTracker.countStats();
16755                for (int i=0; i<N; i++) {
16756                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16757                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
16758                        if (mi == null) {
16759                            mi = new Debug.MemoryInfo();
16760                        }
16761                        if (!brief && !oomOnly) {
16762                            Debug.getMemoryInfo(st.pid, mi);
16763                        } else {
16764                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
16765                            mi.nativePrivateDirty = (int)tmpLong[0];
16766                        }
16767
16768                        final long myTotalPss = mi.getTotalPss();
16769                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16770                        totalPss += myTotalPss;
16771                        nativeProcTotalPss += myTotalPss;
16772
16773                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16774                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16775                        procMems.add(pssItem);
16776
16777                        nativePss += mi.nativePss;
16778                        nativeSwapPss += mi.nativeSwappedOutPss;
16779                        dalvikPss += mi.dalvikPss;
16780                        dalvikSwapPss += mi.dalvikSwappedOutPss;
16781                        for (int j=0; j<dalvikSubitemPss.length; j++) {
16782                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16783                            dalvikSubitemSwapPss[j] +=
16784                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16785                        }
16786                        otherPss += mi.otherPss;
16787                        otherSwapPss += mi.otherSwappedOutPss;
16788                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16789                            long mem = mi.getOtherPss(j);
16790                            miscPss[j] += mem;
16791                            otherPss -= mem;
16792                            mem = mi.getOtherSwappedOutPss(j);
16793                            miscSwapPss[j] += mem;
16794                            otherSwapPss -= mem;
16795                        }
16796                        oomPss[0] += myTotalPss;
16797                        oomSwapPss[0] += myTotalSwapPss;
16798                        if (oomProcs[0] == null) {
16799                            oomProcs[0] = new ArrayList<MemItem>();
16800                        }
16801                        oomProcs[0].add(pssItem);
16802                    }
16803                }
16804            }
16805
16806            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16807
16808            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16809            final MemItem dalvikItem =
16810                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16811            if (dalvikSubitemPss.length > 0) {
16812                dalvikItem.subitems = new ArrayList<MemItem>();
16813                for (int j=0; j<dalvikSubitemPss.length; j++) {
16814                    final String name = Debug.MemoryInfo.getOtherLabel(
16815                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
16816                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16817                                    dalvikSubitemSwapPss[j], j));
16818                }
16819            }
16820            catMems.add(dalvikItem);
16821            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16822            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16823                String label = Debug.MemoryInfo.getOtherLabel(j);
16824                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16825            }
16826
16827            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16828            for (int j=0; j<oomPss.length; j++) {
16829                if (oomPss[j] != 0) {
16830                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16831                            : DUMP_MEM_OOM_LABEL[j];
16832                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16833                            DUMP_MEM_OOM_ADJ[j]);
16834                    item.subitems = oomProcs[j];
16835                    oomMems.add(item);
16836                }
16837            }
16838
16839            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16840            if (!brief && !oomOnly && !isCompact) {
16841                pw.println();
16842                pw.println("Total PSS by process:");
16843                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
16844                pw.println();
16845            }
16846            if (!isCompact) {
16847                pw.println("Total PSS by OOM adjustment:");
16848            }
16849            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
16850            if (!brief && !oomOnly) {
16851                PrintWriter out = categoryPw != null ? categoryPw : pw;
16852                if (!isCompact) {
16853                    out.println();
16854                    out.println("Total PSS by category:");
16855                }
16856                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
16857            }
16858            if (!isCompact) {
16859                pw.println();
16860            }
16861            MemInfoReader memInfo = new MemInfoReader();
16862            memInfo.readMemInfo();
16863            if (nativeProcTotalPss > 0) {
16864                synchronized (this) {
16865                    final long cachedKb = memInfo.getCachedSizeKb();
16866                    final long freeKb = memInfo.getFreeSizeKb();
16867                    final long zramKb = memInfo.getZramTotalSizeKb();
16868                    final long kernelKb = memInfo.getKernelUsedSizeKb();
16869                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16870                            kernelKb*1024, nativeProcTotalPss*1024);
16871                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16872                            nativeProcTotalPss);
16873                }
16874            }
16875            if (!brief) {
16876                if (!isCompact) {
16877                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16878                    pw.print(" (status ");
16879                    switch (mLastMemoryLevel) {
16880                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16881                            pw.println("normal)");
16882                            break;
16883                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16884                            pw.println("moderate)");
16885                            break;
16886                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
16887                            pw.println("low)");
16888                            break;
16889                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16890                            pw.println("critical)");
16891                            break;
16892                        default:
16893                            pw.print(mLastMemoryLevel);
16894                            pw.println(")");
16895                            break;
16896                    }
16897                    pw.print(" Free RAM: ");
16898                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16899                            + memInfo.getFreeSizeKb()));
16900                    pw.print(" (");
16901                    pw.print(stringifyKBSize(cachedPss));
16902                    pw.print(" cached pss + ");
16903                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16904                    pw.print(" cached kernel + ");
16905                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16906                    pw.println(" free)");
16907                } else {
16908                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16909                    pw.print(cachedPss + memInfo.getCachedSizeKb()
16910                            + memInfo.getFreeSizeKb()); pw.print(",");
16911                    pw.println(totalPss - cachedPss);
16912                }
16913            }
16914            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16915                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16916                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16917            if (!isCompact) {
16918                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16919                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16920                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16921                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16922                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16923            } else {
16924                pw.print("lostram,"); pw.println(lostRAM);
16925            }
16926            if (!brief) {
16927                if (memInfo.getZramTotalSizeKb() != 0) {
16928                    if (!isCompact) {
16929                        pw.print("     ZRAM: ");
16930                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16931                                pw.print(" physical used for ");
16932                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16933                                        - memInfo.getSwapFreeSizeKb()));
16934                                pw.print(" in swap (");
16935                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16936                                pw.println(" total swap)");
16937                    } else {
16938                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16939                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16940                                pw.println(memInfo.getSwapFreeSizeKb());
16941                    }
16942                }
16943                final long[] ksm = getKsmInfo();
16944                if (!isCompact) {
16945                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16946                            || ksm[KSM_VOLATILE] != 0) {
16947                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16948                                pw.print(" saved from shared ");
16949                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16950                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16951                                pw.print(" unshared; ");
16952                                pw.print(stringifyKBSize(
16953                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
16954                    }
16955                    pw.print("   Tuning: ");
16956                    pw.print(ActivityManager.staticGetMemoryClass());
16957                    pw.print(" (large ");
16958                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16959                    pw.print("), oom ");
16960                    pw.print(stringifySize(
16961                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16962                    pw.print(", restore limit ");
16963                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16964                    if (ActivityManager.isLowRamDeviceStatic()) {
16965                        pw.print(" (low-ram)");
16966                    }
16967                    if (ActivityManager.isHighEndGfx()) {
16968                        pw.print(" (high-end-gfx)");
16969                    }
16970                    pw.println();
16971                } else {
16972                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16973                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16974                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16975                    pw.print("tuning,");
16976                    pw.print(ActivityManager.staticGetMemoryClass());
16977                    pw.print(',');
16978                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16979                    pw.print(',');
16980                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16981                    if (ActivityManager.isLowRamDeviceStatic()) {
16982                        pw.print(",low-ram");
16983                    }
16984                    if (ActivityManager.isHighEndGfx()) {
16985                        pw.print(",high-end-gfx");
16986                    }
16987                    pw.println();
16988                }
16989            }
16990        }
16991    }
16992
16993    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16994            long memtrack, String name) {
16995        sb.append("  ");
16996        sb.append(ProcessList.makeOomAdjString(oomAdj));
16997        sb.append(' ');
16998        sb.append(ProcessList.makeProcStateString(procState));
16999        sb.append(' ');
17000        ProcessList.appendRamKb(sb, pss);
17001        sb.append(": ");
17002        sb.append(name);
17003        if (memtrack > 0) {
17004            sb.append(" (");
17005            sb.append(stringifyKBSize(memtrack));
17006            sb.append(" memtrack)");
17007        }
17008    }
17009
17010    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
17011        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
17012        sb.append(" (pid ");
17013        sb.append(mi.pid);
17014        sb.append(") ");
17015        sb.append(mi.adjType);
17016        sb.append('\n');
17017        if (mi.adjReason != null) {
17018            sb.append("                      ");
17019            sb.append(mi.adjReason);
17020            sb.append('\n');
17021        }
17022    }
17023
17024    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
17025        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
17026        for (int i=0, N=memInfos.size(); i<N; i++) {
17027            ProcessMemInfo mi = memInfos.get(i);
17028            infoMap.put(mi.pid, mi);
17029        }
17030        updateCpuStatsNow();
17031        long[] memtrackTmp = new long[1];
17032        final List<ProcessCpuTracker.Stats> stats;
17033        // Get a list of Stats that have vsize > 0
17034        synchronized (mProcessCpuTracker) {
17035            stats = mProcessCpuTracker.getStats((st) -> {
17036                return st.vsize > 0;
17037            });
17038        }
17039        final int statsCount = stats.size();
17040        for (int i = 0; i < statsCount; i++) {
17041            ProcessCpuTracker.Stats st = stats.get(i);
17042            long pss = Debug.getPss(st.pid, null, memtrackTmp);
17043            if (pss > 0) {
17044                if (infoMap.indexOfKey(st.pid) < 0) {
17045                    ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
17046                            ProcessList.NATIVE_ADJ, -1, "native", null);
17047                    mi.pss = pss;
17048                    mi.memtrack = memtrackTmp[0];
17049                    memInfos.add(mi);
17050                }
17051            }
17052        }
17053
17054        long totalPss = 0;
17055        long totalMemtrack = 0;
17056        for (int i=0, N=memInfos.size(); i<N; i++) {
17057            ProcessMemInfo mi = memInfos.get(i);
17058            if (mi.pss == 0) {
17059                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
17060                mi.memtrack = memtrackTmp[0];
17061            }
17062            totalPss += mi.pss;
17063            totalMemtrack += mi.memtrack;
17064        }
17065        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
17066            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
17067                if (lhs.oomAdj != rhs.oomAdj) {
17068                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
17069                }
17070                if (lhs.pss != rhs.pss) {
17071                    return lhs.pss < rhs.pss ? 1 : -1;
17072                }
17073                return 0;
17074            }
17075        });
17076
17077        StringBuilder tag = new StringBuilder(128);
17078        StringBuilder stack = new StringBuilder(128);
17079        tag.append("Low on memory -- ");
17080        appendMemBucket(tag, totalPss, "total", false);
17081        appendMemBucket(stack, totalPss, "total", true);
17082
17083        StringBuilder fullNativeBuilder = new StringBuilder(1024);
17084        StringBuilder shortNativeBuilder = new StringBuilder(1024);
17085        StringBuilder fullJavaBuilder = new StringBuilder(1024);
17086
17087        boolean firstLine = true;
17088        int lastOomAdj = Integer.MIN_VALUE;
17089        long extraNativeRam = 0;
17090        long extraNativeMemtrack = 0;
17091        long cachedPss = 0;
17092        for (int i=0, N=memInfos.size(); i<N; i++) {
17093            ProcessMemInfo mi = memInfos.get(i);
17094
17095            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17096                cachedPss += mi.pss;
17097            }
17098
17099            if (mi.oomAdj != ProcessList.NATIVE_ADJ
17100                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
17101                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
17102                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
17103                if (lastOomAdj != mi.oomAdj) {
17104                    lastOomAdj = mi.oomAdj;
17105                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17106                        tag.append(" / ");
17107                    }
17108                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
17109                        if (firstLine) {
17110                            stack.append(":");
17111                            firstLine = false;
17112                        }
17113                        stack.append("\n\t at ");
17114                    } else {
17115                        stack.append("$");
17116                    }
17117                } else {
17118                    tag.append(" ");
17119                    stack.append("$");
17120                }
17121                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17122                    appendMemBucket(tag, mi.pss, mi.name, false);
17123                }
17124                appendMemBucket(stack, mi.pss, mi.name, true);
17125                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
17126                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
17127                    stack.append("(");
17128                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
17129                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
17130                            stack.append(DUMP_MEM_OOM_LABEL[k]);
17131                            stack.append(":");
17132                            stack.append(DUMP_MEM_OOM_ADJ[k]);
17133                        }
17134                    }
17135                    stack.append(")");
17136                }
17137            }
17138
17139            appendMemInfo(fullNativeBuilder, mi);
17140            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
17141                // The short form only has native processes that are >= 512K.
17142                if (mi.pss >= 512) {
17143                    appendMemInfo(shortNativeBuilder, mi);
17144                } else {
17145                    extraNativeRam += mi.pss;
17146                    extraNativeMemtrack += mi.memtrack;
17147                }
17148            } else {
17149                // Short form has all other details, but if we have collected RAM
17150                // from smaller native processes let's dump a summary of that.
17151                if (extraNativeRam > 0) {
17152                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
17153                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
17154                    shortNativeBuilder.append('\n');
17155                    extraNativeRam = 0;
17156                }
17157                appendMemInfo(fullJavaBuilder, mi);
17158            }
17159        }
17160
17161        fullJavaBuilder.append("           ");
17162        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
17163        fullJavaBuilder.append(": TOTAL");
17164        if (totalMemtrack > 0) {
17165            fullJavaBuilder.append(" (");
17166            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
17167            fullJavaBuilder.append(" memtrack)");
17168        } else {
17169        }
17170        fullJavaBuilder.append("\n");
17171
17172        MemInfoReader memInfo = new MemInfoReader();
17173        memInfo.readMemInfo();
17174        final long[] infos = memInfo.getRawInfo();
17175
17176        StringBuilder memInfoBuilder = new StringBuilder(1024);
17177        Debug.getMemInfo(infos);
17178        memInfoBuilder.append("  MemInfo: ");
17179        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
17180        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
17181        memInfoBuilder.append(stringifyKBSize(
17182                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
17183        memInfoBuilder.append(stringifyKBSize(
17184                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
17185        memInfoBuilder.append(stringifyKBSize(
17186                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
17187        memInfoBuilder.append("           ");
17188        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
17189        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
17190        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
17191        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
17192        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
17193            memInfoBuilder.append("  ZRAM: ");
17194            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
17195            memInfoBuilder.append(" RAM, ");
17196            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
17197            memInfoBuilder.append(" swap total, ");
17198            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
17199            memInfoBuilder.append(" swap free\n");
17200        }
17201        final long[] ksm = getKsmInfo();
17202        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17203                || ksm[KSM_VOLATILE] != 0) {
17204            memInfoBuilder.append("  KSM: ");
17205            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
17206            memInfoBuilder.append(" saved from shared ");
17207            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
17208            memInfoBuilder.append("\n       ");
17209            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
17210            memInfoBuilder.append(" unshared; ");
17211            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
17212            memInfoBuilder.append(" volatile\n");
17213        }
17214        memInfoBuilder.append("  Free RAM: ");
17215        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17216                + memInfo.getFreeSizeKb()));
17217        memInfoBuilder.append("\n");
17218        memInfoBuilder.append("  Used RAM: ");
17219        memInfoBuilder.append(stringifyKBSize(
17220                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
17221        memInfoBuilder.append("\n");
17222        memInfoBuilder.append("  Lost RAM: ");
17223        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
17224                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17225                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
17226        memInfoBuilder.append("\n");
17227        Slog.i(TAG, "Low on memory:");
17228        Slog.i(TAG, shortNativeBuilder.toString());
17229        Slog.i(TAG, fullJavaBuilder.toString());
17230        Slog.i(TAG, memInfoBuilder.toString());
17231
17232        StringBuilder dropBuilder = new StringBuilder(1024);
17233        /*
17234        StringWriter oomSw = new StringWriter();
17235        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
17236        StringWriter catSw = new StringWriter();
17237        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17238        String[] emptyArgs = new String[] { };
17239        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
17240        oomPw.flush();
17241        String oomString = oomSw.toString();
17242        */
17243        dropBuilder.append("Low on memory:");
17244        dropBuilder.append(stack);
17245        dropBuilder.append('\n');
17246        dropBuilder.append(fullNativeBuilder);
17247        dropBuilder.append(fullJavaBuilder);
17248        dropBuilder.append('\n');
17249        dropBuilder.append(memInfoBuilder);
17250        dropBuilder.append('\n');
17251        /*
17252        dropBuilder.append(oomString);
17253        dropBuilder.append('\n');
17254        */
17255        StringWriter catSw = new StringWriter();
17256        synchronized (ActivityManagerService.this) {
17257            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17258            String[] emptyArgs = new String[] { };
17259            catPw.println();
17260            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
17261            catPw.println();
17262            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
17263                    false, null).dumpLocked();
17264            catPw.println();
17265            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
17266            catPw.flush();
17267        }
17268        dropBuilder.append(catSw.toString());
17269        addErrorToDropBox("lowmem", null, "system_server", null,
17270                null, tag.toString(), dropBuilder.toString(), null, null);
17271        //Slog.i(TAG, "Sent to dropbox:");
17272        //Slog.i(TAG, dropBuilder.toString());
17273        synchronized (ActivityManagerService.this) {
17274            long now = SystemClock.uptimeMillis();
17275            if (mLastMemUsageReportTime < now) {
17276                mLastMemUsageReportTime = now;
17277            }
17278        }
17279    }
17280
17281    /**
17282     * Searches array of arguments for the specified string
17283     * @param args array of argument strings
17284     * @param value value to search for
17285     * @return true if the value is contained in the array
17286     */
17287    private static boolean scanArgs(String[] args, String value) {
17288        if (args != null) {
17289            for (String arg : args) {
17290                if (value.equals(arg)) {
17291                    return true;
17292                }
17293            }
17294        }
17295        return false;
17296    }
17297
17298    private final boolean removeDyingProviderLocked(ProcessRecord proc,
17299            ContentProviderRecord cpr, boolean always) {
17300        final boolean inLaunching = mLaunchingProviders.contains(cpr);
17301
17302        if (!inLaunching || always) {
17303            synchronized (cpr) {
17304                cpr.launchingApp = null;
17305                cpr.notifyAll();
17306            }
17307            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
17308            String names[] = cpr.info.authority.split(";");
17309            for (int j = 0; j < names.length; j++) {
17310                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
17311            }
17312        }
17313
17314        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
17315            ContentProviderConnection conn = cpr.connections.get(i);
17316            if (conn.waiting) {
17317                // If this connection is waiting for the provider, then we don't
17318                // need to mess with its process unless we are always removing
17319                // or for some reason the provider is not currently launching.
17320                if (inLaunching && !always) {
17321                    continue;
17322                }
17323            }
17324            ProcessRecord capp = conn.client;
17325            conn.dead = true;
17326            if (conn.stableCount > 0) {
17327                if (!capp.persistent && capp.thread != null
17328                        && capp.pid != 0
17329                        && capp.pid != MY_PID) {
17330                    capp.kill("depends on provider "
17331                            + cpr.name.flattenToShortString()
17332                            + " in dying proc " + (proc != null ? proc.processName : "??")
17333                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
17334                }
17335            } else if (capp.thread != null && conn.provider.provider != null) {
17336                try {
17337                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
17338                } catch (RemoteException e) {
17339                }
17340                // In the protocol here, we don't expect the client to correctly
17341                // clean up this connection, we'll just remove it.
17342                cpr.connections.remove(i);
17343                if (conn.client.conProviders.remove(conn)) {
17344                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
17345                }
17346            }
17347        }
17348
17349        if (inLaunching && always) {
17350            mLaunchingProviders.remove(cpr);
17351        }
17352        return inLaunching;
17353    }
17354
17355    /**
17356     * Main code for cleaning up a process when it has gone away.  This is
17357     * called both as a result of the process dying, or directly when stopping
17358     * a process when running in single process mode.
17359     *
17360     * @return Returns true if the given process has been restarted, so the
17361     * app that was passed in must remain on the process lists.
17362     */
17363    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
17364            boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
17365        Slog.d(TAG, "cleanUpApplicationRecord -- " + app.pid);
17366        if (index >= 0) {
17367            removeLruProcessLocked(app);
17368            ProcessList.remove(app.pid);
17369        }
17370
17371        mProcessesToGc.remove(app);
17372        mPendingPssProcesses.remove(app);
17373
17374        // Dismiss any open dialogs.
17375        if (app.crashDialog != null && !app.forceCrashReport) {
17376            app.crashDialog.dismiss();
17377            app.crashDialog = null;
17378        }
17379        if (app.anrDialog != null) {
17380            app.anrDialog.dismiss();
17381            app.anrDialog = null;
17382        }
17383        if (app.waitDialog != null) {
17384            app.waitDialog.dismiss();
17385            app.waitDialog = null;
17386        }
17387
17388        app.crashing = false;
17389        app.notResponding = false;
17390
17391        app.resetPackageList(mProcessStats);
17392        app.unlinkDeathRecipient();
17393        app.makeInactive(mProcessStats);
17394        app.waitingToKill = null;
17395        app.forcingToForeground = null;
17396        updateProcessForegroundLocked(app, false, false);
17397        app.foregroundActivities = false;
17398        app.hasShownUi = false;
17399        app.treatLikeActivity = false;
17400        app.hasAboveClient = false;
17401        app.hasClientActivities = false;
17402
17403        mServices.killServicesLocked(app, allowRestart);
17404
17405        boolean restart = false;
17406
17407        // Remove published content providers.
17408        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
17409            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
17410            final boolean always = app.bad || !allowRestart;
17411            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
17412            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
17413                // We left the provider in the launching list, need to
17414                // restart it.
17415                restart = true;
17416            }
17417
17418            cpr.provider = null;
17419            cpr.proc = null;
17420        }
17421        app.pubProviders.clear();
17422
17423        // Take care of any launching providers waiting for this process.
17424        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
17425            restart = true;
17426        }
17427
17428        // Unregister from connected content providers.
17429        if (!app.conProviders.isEmpty()) {
17430            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
17431                ContentProviderConnection conn = app.conProviders.get(i);
17432                conn.provider.connections.remove(conn);
17433                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
17434                        conn.provider.name);
17435            }
17436            app.conProviders.clear();
17437        }
17438
17439        // At this point there may be remaining entries in mLaunchingProviders
17440        // where we were the only one waiting, so they are no longer of use.
17441        // Look for these and clean up if found.
17442        // XXX Commented out for now.  Trying to figure out a way to reproduce
17443        // the actual situation to identify what is actually going on.
17444        if (false) {
17445            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17446                ContentProviderRecord cpr = mLaunchingProviders.get(i);
17447                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
17448                    synchronized (cpr) {
17449                        cpr.launchingApp = null;
17450                        cpr.notifyAll();
17451                    }
17452                }
17453            }
17454        }
17455
17456        skipCurrentReceiverLocked(app);
17457
17458        // Unregister any receivers.
17459        for (int i = app.receivers.size() - 1; i >= 0; i--) {
17460            removeReceiverLocked(app.receivers.valueAt(i));
17461        }
17462        app.receivers.clear();
17463
17464        // If the app is undergoing backup, tell the backup manager about it
17465        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
17466            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
17467                    + mBackupTarget.appInfo + " died during backup");
17468            mHandler.post(new Runnable() {
17469                @Override
17470                public void run(){
17471                    try {
17472                        IBackupManager bm = IBackupManager.Stub.asInterface(
17473                                ServiceManager.getService(Context.BACKUP_SERVICE));
17474                        bm.agentDisconnected(app.info.packageName);
17475                    } catch (RemoteException e) {
17476                        // can't happen; backup manager is local
17477                    }
17478                }
17479            });
17480        }
17481
17482        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
17483            ProcessChangeItem item = mPendingProcessChanges.get(i);
17484            if (item.pid == app.pid) {
17485                mPendingProcessChanges.remove(i);
17486                mAvailProcessChanges.add(item);
17487            }
17488        }
17489        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
17490                null).sendToTarget();
17491
17492        // If the caller is restarting this app, then leave it in its
17493        // current lists and let the caller take care of it.
17494        if (restarting) {
17495            return false;
17496        }
17497
17498        if (!app.persistent || app.isolated) {
17499            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
17500                    "Removing non-persistent process during cleanup: " + app);
17501            if (!replacingPid) {
17502                removeProcessNameLocked(app.processName, app.uid, app);
17503            }
17504            if (mHeavyWeightProcess == app) {
17505                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
17506                        mHeavyWeightProcess.userId, 0));
17507                mHeavyWeightProcess = null;
17508            }
17509        } else if (!app.removed) {
17510            // This app is persistent, so we need to keep its record around.
17511            // If it is not already on the pending app list, add it there
17512            // and start a new process for it.
17513            if (mPersistentStartingProcesses.indexOf(app) < 0) {
17514                mPersistentStartingProcesses.add(app);
17515                restart = true;
17516            }
17517        }
17518        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
17519                TAG_CLEANUP, "Clean-up removing on hold: " + app);
17520        mProcessesOnHold.remove(app);
17521
17522        if (app == mHomeProcess) {
17523            mHomeProcess = null;
17524        }
17525        if (app == mPreviousProcess) {
17526            mPreviousProcess = null;
17527        }
17528
17529        if (restart && !app.isolated) {
17530            // We have components that still need to be running in the
17531            // process, so re-launch it.
17532            if (index < 0) {
17533                ProcessList.remove(app.pid);
17534            }
17535            addProcessNameLocked(app);
17536            startProcessLocked(app, "restart", app.processName);
17537            return true;
17538        } else if (app.pid > 0 && app.pid != MY_PID) {
17539            // Goodbye!
17540            boolean removed;
17541            synchronized (mPidsSelfLocked) {
17542                mPidsSelfLocked.remove(app.pid);
17543                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
17544            }
17545            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
17546            if (app.isolated) {
17547                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
17548            }
17549            app.setPid(0);
17550        }
17551        return false;
17552    }
17553
17554    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
17555        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17556            ContentProviderRecord cpr = mLaunchingProviders.get(i);
17557            if (cpr.launchingApp == app) {
17558                return true;
17559            }
17560        }
17561        return false;
17562    }
17563
17564    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
17565        // Look through the content providers we are waiting to have launched,
17566        // and if any run in this process then either schedule a restart of
17567        // the process or kill the client waiting for it if this process has
17568        // gone bad.
17569        boolean restart = false;
17570        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17571            ContentProviderRecord cpr = mLaunchingProviders.get(i);
17572            if (cpr.launchingApp == app) {
17573                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
17574                    restart = true;
17575                } else {
17576                    removeDyingProviderLocked(app, cpr, true);
17577                }
17578            }
17579        }
17580        return restart;
17581    }
17582
17583    // =========================================================
17584    // SERVICES
17585    // =========================================================
17586
17587    @Override
17588    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
17589            int flags) {
17590        enforceNotIsolatedCaller("getServices");
17591
17592        final int callingUid = Binder.getCallingUid();
17593        final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission(
17594            INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED);
17595        final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
17596            callingUid);
17597        synchronized (this) {
17598            return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
17599                allowed, canInteractAcrossUsers);
17600        }
17601    }
17602
17603    @Override
17604    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
17605        enforceNotIsolatedCaller("getRunningServiceControlPanel");
17606        synchronized (this) {
17607            return mServices.getRunningServiceControlPanelLocked(name);
17608        }
17609    }
17610
17611    @Override
17612    public ComponentName startService(IApplicationThread caller, Intent service,
17613            String resolvedType, int id, Notification notification,
17614            String callingPackage, int userId)
17615            throws TransactionTooLargeException {
17616        enforceNotIsolatedCaller("startService");
17617        // Refuse possible leaked file descriptors
17618        if (service != null && service.hasFileDescriptors() == true) {
17619            throw new IllegalArgumentException("File descriptors passed in Intent");
17620        }
17621
17622        if (callingPackage == null) {
17623            throw new IllegalArgumentException("callingPackage cannot be null");
17624        }
17625
17626        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17627                "startService: " + service + " type=" + resolvedType);
17628        synchronized(this) {
17629            final int callingPid = Binder.getCallingPid();
17630            final int callingUid = Binder.getCallingUid();
17631            final long origId = Binder.clearCallingIdentity();
17632            ComponentName res = mServices.startServiceLocked(caller, service,
17633                    resolvedType, id, notification,
17634                    callingPid, callingUid, callingPackage, userId);
17635            Binder.restoreCallingIdentity(origId);
17636            return res;
17637        }
17638    }
17639
17640    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
17641            String callingPackage, int userId)
17642            throws TransactionTooLargeException {
17643        synchronized(this) {
17644            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17645                    "startServiceInPackage: " + service + " type=" + resolvedType);
17646            final long origId = Binder.clearCallingIdentity();
17647            ComponentName res = mServices.startServiceLocked(null, service,
17648                    resolvedType, 0, null, -1, uid, callingPackage, userId);
17649            Binder.restoreCallingIdentity(origId);
17650            return res;
17651        }
17652    }
17653
17654    @Override
17655    public int stopService(IApplicationThread caller, Intent service,
17656            String resolvedType, int userId) {
17657        enforceNotIsolatedCaller("stopService");
17658        // Refuse possible leaked file descriptors
17659        if (service != null && service.hasFileDescriptors() == true) {
17660            throw new IllegalArgumentException("File descriptors passed in Intent");
17661        }
17662
17663        synchronized(this) {
17664            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
17665        }
17666    }
17667
17668    @Override
17669    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
17670        enforceNotIsolatedCaller("peekService");
17671        // Refuse possible leaked file descriptors
17672        if (service != null && service.hasFileDescriptors() == true) {
17673            throw new IllegalArgumentException("File descriptors passed in Intent");
17674        }
17675
17676        if (callingPackage == null) {
17677            throw new IllegalArgumentException("callingPackage cannot be null");
17678        }
17679
17680        synchronized(this) {
17681            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
17682        }
17683    }
17684
17685    @Override
17686    public boolean stopServiceToken(ComponentName className, IBinder token,
17687            int startId) {
17688        synchronized(this) {
17689            return mServices.stopServiceTokenLocked(className, token, startId);
17690        }
17691    }
17692
17693    @Override
17694    public void setServiceForeground(ComponentName className, IBinder token,
17695            int id, Notification notification, int flags) {
17696        synchronized(this) {
17697            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
17698        }
17699    }
17700
17701    @Override
17702    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
17703            boolean requireFull, String name, String callerPackage) {
17704        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
17705                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
17706    }
17707
17708    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
17709            String className, int flags) {
17710        boolean result = false;
17711        // For apps that don't have pre-defined UIDs, check for permission
17712        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
17713            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17714                if (ActivityManager.checkUidPermission(
17715                        INTERACT_ACROSS_USERS,
17716                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
17717                    ComponentName comp = new ComponentName(aInfo.packageName, className);
17718                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
17719                            + " requests FLAG_SINGLE_USER, but app does not hold "
17720                            + INTERACT_ACROSS_USERS;
17721                    Slog.w(TAG, msg);
17722                    throw new SecurityException(msg);
17723                }
17724                // Permission passed
17725                result = true;
17726            }
17727        } else if ("system".equals(componentProcessName)) {
17728            result = true;
17729        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17730            // Phone app and persistent apps are allowed to export singleuser providers.
17731            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
17732                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
17733        }
17734        if (DEBUG_MU) Slog.v(TAG_MU,
17735                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
17736                + Integer.toHexString(flags) + ") = " + result);
17737        return result;
17738    }
17739
17740    /**
17741     * Checks to see if the caller is in the same app as the singleton
17742     * component, or the component is in a special app. It allows special apps
17743     * to export singleton components but prevents exporting singleton
17744     * components for regular apps.
17745     */
17746    boolean isValidSingletonCall(int callingUid, int componentUid) {
17747        int componentAppId = UserHandle.getAppId(componentUid);
17748        return UserHandle.isSameApp(callingUid, componentUid)
17749                || componentAppId == Process.SYSTEM_UID
17750                || componentAppId == Process.PHONE_UID
17751                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
17752                        == PackageManager.PERMISSION_GRANTED;
17753    }
17754
17755    public int bindService(IApplicationThread caller, IBinder token, Intent service,
17756            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
17757            int userId) throws TransactionTooLargeException {
17758        enforceNotIsolatedCaller("bindService");
17759
17760        // Refuse possible leaked file descriptors
17761        if (service != null && service.hasFileDescriptors() == true) {
17762            throw new IllegalArgumentException("File descriptors passed in Intent");
17763        }
17764
17765        if (callingPackage == null) {
17766            throw new IllegalArgumentException("callingPackage cannot be null");
17767        }
17768
17769        synchronized(this) {
17770            return mServices.bindServiceLocked(caller, token, service,
17771                    resolvedType, connection, flags, callingPackage, userId);
17772        }
17773    }
17774
17775    public boolean unbindService(IServiceConnection connection) {
17776        synchronized (this) {
17777            return mServices.unbindServiceLocked(connection);
17778        }
17779    }
17780
17781    public void publishService(IBinder token, Intent intent, IBinder service) {
17782        // Refuse possible leaked file descriptors
17783        if (intent != null && intent.hasFileDescriptors() == true) {
17784            throw new IllegalArgumentException("File descriptors passed in Intent");
17785        }
17786
17787        synchronized(this) {
17788            if (!(token instanceof ServiceRecord)) {
17789                throw new IllegalArgumentException("Invalid service token");
17790            }
17791            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17792        }
17793    }
17794
17795    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17796        // Refuse possible leaked file descriptors
17797        if (intent != null && intent.hasFileDescriptors() == true) {
17798            throw new IllegalArgumentException("File descriptors passed in Intent");
17799        }
17800
17801        synchronized(this) {
17802            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17803        }
17804    }
17805
17806    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17807        synchronized(this) {
17808            if (!(token instanceof ServiceRecord)) {
17809                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17810                throw new IllegalArgumentException("Invalid service token");
17811            }
17812            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17813        }
17814    }
17815
17816    // =========================================================
17817    // BACKUP AND RESTORE
17818    // =========================================================
17819
17820    // Cause the target app to be launched if necessary and its backup agent
17821    // instantiated.  The backup agent will invoke backupAgentCreated() on the
17822    // activity manager to announce its creation.
17823    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
17824        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
17825        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17826
17827        IPackageManager pm = AppGlobals.getPackageManager();
17828        ApplicationInfo app = null;
17829        try {
17830            app = pm.getApplicationInfo(packageName, 0, userId);
17831        } catch (RemoteException e) {
17832            // can't happen; package manager is process-local
17833        }
17834        if (app == null) {
17835            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
17836            return false;
17837        }
17838
17839        synchronized(this) {
17840            // !!! TODO: currently no check here that we're already bound
17841            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17842            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17843            synchronized (stats) {
17844                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17845            }
17846
17847            // Backup agent is now in use, its package can't be stopped.
17848            try {
17849                AppGlobals.getPackageManager().setPackageStoppedState(
17850                        app.packageName, false, UserHandle.getUserId(app.uid));
17851            } catch (RemoteException e) {
17852            } catch (IllegalArgumentException e) {
17853                Slog.w(TAG, "Failed trying to unstop package "
17854                        + app.packageName + ": " + e);
17855            }
17856
17857            BackupRecord r = new BackupRecord(ss, app, backupMode);
17858            ComponentName hostingName =
17859                    (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
17860                            ? new ComponentName(app.packageName, app.backupAgentName)
17861                            : new ComponentName("android", "FullBackupAgent");
17862            // startProcessLocked() returns existing proc's record if it's already running
17863            ProcessRecord proc = startProcessLocked(app.processName, app,
17864                    false, 0, "backup", hostingName, false, false, false);
17865            if (proc == null) {
17866                Slog.e(TAG, "Unable to start backup agent process " + r);
17867                return false;
17868            }
17869
17870            // If the app is a regular app (uid >= 10000) and not the system server or phone
17871            // process, etc, then mark it as being in full backup so that certain calls to the
17872            // process can be blocked. This is not reset to false anywhere because we kill the
17873            // process after the full backup is done and the ProcessRecord will vaporize anyway.
17874            if (UserHandle.isApp(app.uid) &&
17875                    backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
17876                proc.inFullBackup = true;
17877            }
17878            r.app = proc;
17879            mBackupTarget = r;
17880            mBackupAppName = app.packageName;
17881
17882            // Try not to kill the process during backup
17883            updateOomAdjLocked(proc);
17884
17885            // If the process is already attached, schedule the creation of the backup agent now.
17886            // If it is not yet live, this will be done when it attaches to the framework.
17887            if (proc.thread != null) {
17888                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17889                try {
17890                    proc.thread.scheduleCreateBackupAgent(app,
17891                            compatibilityInfoForPackageLocked(app), backupMode);
17892                } catch (RemoteException e) {
17893                    // Will time out on the backup manager side
17894                }
17895            } else {
17896                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17897            }
17898            // Invariants: at this point, the target app process exists and the application
17899            // is either already running or in the process of coming up.  mBackupTarget and
17900            // mBackupAppName describe the app, so that when it binds back to the AM we
17901            // know that it's scheduled for a backup-agent operation.
17902        }
17903
17904        return true;
17905    }
17906
17907    @Override
17908    public void clearPendingBackup() {
17909        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17910        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17911
17912        synchronized (this) {
17913            mBackupTarget = null;
17914            mBackupAppName = null;
17915        }
17916    }
17917
17918    // A backup agent has just come up
17919    public void backupAgentCreated(String agentPackageName, IBinder agent) {
17920        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17921                + " = " + agent);
17922
17923        synchronized(this) {
17924            if (!agentPackageName.equals(mBackupAppName)) {
17925                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17926                return;
17927            }
17928        }
17929
17930        long oldIdent = Binder.clearCallingIdentity();
17931        try {
17932            IBackupManager bm = IBackupManager.Stub.asInterface(
17933                    ServiceManager.getService(Context.BACKUP_SERVICE));
17934            bm.agentConnected(agentPackageName, agent);
17935        } catch (RemoteException e) {
17936            // can't happen; the backup manager service is local
17937        } catch (Exception e) {
17938            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17939            e.printStackTrace();
17940        } finally {
17941            Binder.restoreCallingIdentity(oldIdent);
17942        }
17943    }
17944
17945    // done with this agent
17946    public void unbindBackupAgent(ApplicationInfo appInfo) {
17947        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17948        if (appInfo == null) {
17949            Slog.w(TAG, "unbind backup agent for null app");
17950            return;
17951        }
17952
17953        synchronized(this) {
17954            try {
17955                if (mBackupAppName == null) {
17956                    Slog.w(TAG, "Unbinding backup agent with no active backup");
17957                    return;
17958                }
17959
17960                if (!mBackupAppName.equals(appInfo.packageName)) {
17961                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17962                    return;
17963                }
17964
17965                // Not backing this app up any more; reset its OOM adjustment
17966                final ProcessRecord proc = mBackupTarget.app;
17967                updateOomAdjLocked(proc);
17968                proc.inFullBackup = false;
17969
17970                // If the app crashed during backup, 'thread' will be null here
17971                if (proc.thread != null) {
17972                    try {
17973                        proc.thread.scheduleDestroyBackupAgent(appInfo,
17974                                compatibilityInfoForPackageLocked(appInfo));
17975                    } catch (Exception e) {
17976                        Slog.e(TAG, "Exception when unbinding backup agent:");
17977                        e.printStackTrace();
17978                    }
17979                }
17980            } finally {
17981                mBackupTarget = null;
17982                mBackupAppName = null;
17983            }
17984        }
17985    }
17986    // =========================================================
17987    // BROADCASTS
17988    // =========================================================
17989
17990    boolean isPendingBroadcastProcessLocked(int pid) {
17991        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17992                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17993    }
17994
17995    void skipPendingBroadcastLocked(int pid) {
17996            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17997            for (BroadcastQueue queue : mBroadcastQueues) {
17998                queue.skipPendingBroadcastLocked(pid);
17999            }
18000    }
18001
18002    // The app just attached; send any pending broadcasts that it should receive
18003    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
18004        boolean didSomething = false;
18005        for (BroadcastQueue queue : mBroadcastQueues) {
18006            didSomething |= queue.sendPendingBroadcastsLocked(app);
18007        }
18008        return didSomething;
18009    }
18010
18011    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
18012            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
18013        enforceNotIsolatedCaller("registerReceiver");
18014        ArrayList<Intent> stickyIntents = null;
18015        ProcessRecord callerApp = null;
18016        int callingUid;
18017        int callingPid;
18018        synchronized(this) {
18019            if (caller != null) {
18020                callerApp = getRecordForAppLocked(caller);
18021                if (callerApp == null) {
18022                    throw new SecurityException(
18023                            "Unable to find app for caller " + caller
18024                            + " (pid=" + Binder.getCallingPid()
18025                            + ") when registering receiver " + receiver);
18026                }
18027                if (callerApp.info.uid != Process.SYSTEM_UID &&
18028                        !callerApp.pkgList.containsKey(callerPackage) &&
18029                        !"android".equals(callerPackage)) {
18030                    throw new SecurityException("Given caller package " + callerPackage
18031                            + " is not running in process " + callerApp);
18032                }
18033                callingUid = callerApp.info.uid;
18034                callingPid = callerApp.pid;
18035            } else {
18036                callerPackage = null;
18037                callingUid = Binder.getCallingUid();
18038                callingPid = Binder.getCallingPid();
18039            }
18040
18041            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
18042                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
18043
18044            Iterator<String> actions = filter.actionsIterator();
18045            if (actions == null) {
18046                ArrayList<String> noAction = new ArrayList<String>(1);
18047                noAction.add(null);
18048                actions = noAction.iterator();
18049            }
18050
18051            // Collect stickies of users
18052            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
18053            while (actions.hasNext()) {
18054                String action = actions.next();
18055                for (int id : userIds) {
18056                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
18057                    if (stickies != null) {
18058                        ArrayList<Intent> intents = stickies.get(action);
18059                        if (intents != null) {
18060                            if (stickyIntents == null) {
18061                                stickyIntents = new ArrayList<Intent>();
18062                            }
18063                            stickyIntents.addAll(intents);
18064                        }
18065                    }
18066                }
18067            }
18068        }
18069
18070        ArrayList<Intent> allSticky = null;
18071        if (stickyIntents != null) {
18072            final ContentResolver resolver = mContext.getContentResolver();
18073            // Look for any matching sticky broadcasts...
18074            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
18075                Intent intent = stickyIntents.get(i);
18076                // If intent has scheme "content", it will need to acccess
18077                // provider that needs to lock mProviderMap in ActivityThread
18078                // and also it may need to wait application response, so we
18079                // cannot lock ActivityManagerService here.
18080                if (filter.match(resolver, intent, true, TAG) >= 0) {
18081                    if (allSticky == null) {
18082                        allSticky = new ArrayList<Intent>();
18083                    }
18084                    allSticky.add(intent);
18085                }
18086            }
18087        }
18088
18089        // The first sticky in the list is returned directly back to the client.
18090        Intent sticky = allSticky != null ? allSticky.get(0) : null;
18091        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
18092        if (receiver == null) {
18093            return sticky;
18094        }
18095
18096        synchronized (this) {
18097            if (callerApp != null && (callerApp.thread == null
18098                    || callerApp.thread.asBinder() != caller.asBinder())) {
18099                // Original caller already died
18100                return null;
18101            }
18102            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18103            if (rl == null) {
18104                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
18105                        userId, receiver);
18106                if (rl.app != null) {
18107                    rl.app.receivers.add(rl);
18108                } else {
18109                    try {
18110                        receiver.asBinder().linkToDeath(rl, 0);
18111                    } catch (RemoteException e) {
18112                        return sticky;
18113                    }
18114                    rl.linkedToDeath = true;
18115                }
18116                mRegisteredReceivers.put(receiver.asBinder(), rl);
18117            } else if (rl.uid != callingUid) {
18118                throw new IllegalArgumentException(
18119                        "Receiver requested to register for uid " + callingUid
18120                        + " was previously registered for uid " + rl.uid
18121                        + " callerPackage is " + callerPackage);
18122            } else if (rl.pid != callingPid) {
18123                throw new IllegalArgumentException(
18124                        "Receiver requested to register for pid " + callingPid
18125                        + " was previously registered for pid " + rl.pid
18126                        + " callerPackage is " + callerPackage);
18127            } else if (rl.userId != userId) {
18128                throw new IllegalArgumentException(
18129                        "Receiver requested to register for user " + userId
18130                        + " was previously registered for user " + rl.userId
18131                        + " callerPackage is " + callerPackage);
18132            }
18133            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
18134                    permission, callingUid, userId);
18135            rl.add(bf);
18136            if (!bf.debugCheck()) {
18137                Slog.w(TAG, "==> For Dynamic broadcast");
18138            }
18139            mReceiverResolver.addFilter(bf);
18140
18141            // Enqueue broadcasts for all existing stickies that match
18142            // this filter.
18143            if (allSticky != null) {
18144                ArrayList receivers = new ArrayList();
18145                receivers.add(bf);
18146
18147                final int stickyCount = allSticky.size();
18148                for (int i = 0; i < stickyCount; i++) {
18149                    Intent intent = allSticky.get(i);
18150                    BroadcastQueue queue = broadcastQueueForIntent(intent);
18151                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
18152                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
18153                            null, 0, null, null, false, true, true, -1);
18154                    queue.enqueueParallelBroadcastLocked(r);
18155                    queue.scheduleBroadcastsLocked();
18156                }
18157            }
18158
18159            return sticky;
18160        }
18161    }
18162
18163    public void unregisterReceiver(IIntentReceiver receiver) {
18164        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
18165
18166        final long origId = Binder.clearCallingIdentity();
18167        try {
18168            boolean doTrim = false;
18169
18170            synchronized(this) {
18171                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18172                if (rl != null) {
18173                    final BroadcastRecord r = rl.curBroadcast;
18174                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
18175                        final boolean doNext = r.queue.finishReceiverLocked(
18176                                r, r.resultCode, r.resultData, r.resultExtras,
18177                                r.resultAbort, false);
18178                        if (doNext) {
18179                            doTrim = true;
18180                            r.queue.processNextBroadcast(false);
18181                        }
18182                    }
18183
18184                    if (rl.app != null) {
18185                        rl.app.receivers.remove(rl);
18186                    }
18187                    removeReceiverLocked(rl);
18188                    if (rl.linkedToDeath) {
18189                        rl.linkedToDeath = false;
18190                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
18191                    }
18192                }
18193            }
18194
18195            // If we actually concluded any broadcasts, we might now be able
18196            // to trim the recipients' apps from our working set
18197            if (doTrim) {
18198                trimApplications();
18199                return;
18200            }
18201
18202        } finally {
18203            Binder.restoreCallingIdentity(origId);
18204        }
18205    }
18206
18207    void removeReceiverLocked(ReceiverList rl) {
18208        mRegisteredReceivers.remove(rl.receiver.asBinder());
18209        for (int i = rl.size() - 1; i >= 0; i--) {
18210            mReceiverResolver.removeFilter(rl.get(i));
18211        }
18212    }
18213
18214    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
18215        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18216            ProcessRecord r = mLruProcesses.get(i);
18217            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
18218                try {
18219                    r.thread.dispatchPackageBroadcast(cmd, packages);
18220                } catch (RemoteException ex) {
18221                }
18222            }
18223        }
18224    }
18225
18226    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
18227            int callingUid, int[] users) {
18228        // TODO: come back and remove this assumption to triage all broadcasts
18229        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
18230
18231        List<ResolveInfo> receivers = null;
18232        try {
18233            HashSet<ComponentName> singleUserReceivers = null;
18234            boolean scannedFirstReceivers = false;
18235            for (int user : users) {
18236                // Skip users that have Shell restrictions, with exception of always permitted
18237                // Shell broadcasts
18238                if (callingUid == Process.SHELL_UID
18239                        && mUserController.hasUserRestriction(
18240                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
18241                        && !isPermittedShellBroadcast(intent)) {
18242                    continue;
18243                }
18244                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
18245                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
18246                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
18247                    // If this is not the system user, we need to check for
18248                    // any receivers that should be filtered out.
18249                    for (int i=0; i<newReceivers.size(); i++) {
18250                        ResolveInfo ri = newReceivers.get(i);
18251                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
18252                            newReceivers.remove(i);
18253                            i--;
18254                        }
18255                    }
18256                }
18257                if (newReceivers != null && newReceivers.size() == 0) {
18258                    newReceivers = null;
18259                }
18260                if (receivers == null) {
18261                    receivers = newReceivers;
18262                } else if (newReceivers != null) {
18263                    // We need to concatenate the additional receivers
18264                    // found with what we have do far.  This would be easy,
18265                    // but we also need to de-dup any receivers that are
18266                    // singleUser.
18267                    if (!scannedFirstReceivers) {
18268                        // Collect any single user receivers we had already retrieved.
18269                        scannedFirstReceivers = true;
18270                        for (int i=0; i<receivers.size(); i++) {
18271                            ResolveInfo ri = receivers.get(i);
18272                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18273                                ComponentName cn = new ComponentName(
18274                                        ri.activityInfo.packageName, ri.activityInfo.name);
18275                                if (singleUserReceivers == null) {
18276                                    singleUserReceivers = new HashSet<ComponentName>();
18277                                }
18278                                singleUserReceivers.add(cn);
18279                            }
18280                        }
18281                    }
18282                    // Add the new results to the existing results, tracking
18283                    // and de-dupping single user receivers.
18284                    for (int i=0; i<newReceivers.size(); i++) {
18285                        ResolveInfo ri = newReceivers.get(i);
18286                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18287                            ComponentName cn = new ComponentName(
18288                                    ri.activityInfo.packageName, ri.activityInfo.name);
18289                            if (singleUserReceivers == null) {
18290                                singleUserReceivers = new HashSet<ComponentName>();
18291                            }
18292                            if (!singleUserReceivers.contains(cn)) {
18293                                singleUserReceivers.add(cn);
18294                                receivers.add(ri);
18295                            }
18296                        } else {
18297                            receivers.add(ri);
18298                        }
18299                    }
18300                }
18301            }
18302        } catch (RemoteException ex) {
18303            // pm is in same process, this will never happen.
18304        }
18305        return receivers;
18306    }
18307
18308    private boolean isPermittedShellBroadcast(Intent intent) {
18309        // remote bugreport should always be allowed to be taken
18310        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
18311    }
18312
18313    private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
18314            String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
18315        if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
18316            // Don't yell about broadcasts sent via shell
18317            return;
18318        }
18319
18320        final String action = intent.getAction();
18321        if (isProtectedBroadcast
18322                || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
18323                || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
18324                || Intent.ACTION_MEDIA_BUTTON.equals(action)
18325                || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
18326                || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
18327                || Intent.ACTION_MASTER_CLEAR.equals(action)
18328                || Intent.ACTION_FACTORY_RESET.equals(action)
18329                || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
18330                || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
18331                || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
18332                || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
18333                || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
18334                || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
18335                || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) {
18336            // Broadcast is either protected, or it's a public action that
18337            // we've relaxed, so it's fine for system internals to send.
18338            return;
18339        }
18340
18341        // This broadcast may be a problem...  but there are often system components that
18342        // want to send an internal broadcast to themselves, which is annoying to have to
18343        // explicitly list each action as a protected broadcast, so we will check for that
18344        // one safe case and allow it: an explicit broadcast, only being received by something
18345        // that has protected itself.
18346        if (receivers != null && receivers.size() > 0
18347                && (intent.getPackage() != null || intent.getComponent() != null)) {
18348            boolean allProtected = true;
18349            for (int i = receivers.size()-1; i >= 0; i--) {
18350                Object target = receivers.get(i);
18351                if (target instanceof ResolveInfo) {
18352                    ResolveInfo ri = (ResolveInfo)target;
18353                    if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
18354                        allProtected = false;
18355                        break;
18356                    }
18357                } else {
18358                    BroadcastFilter bf = (BroadcastFilter)target;
18359                    if (bf.requiredPermission == null) {
18360                        allProtected = false;
18361                        break;
18362                    }
18363                }
18364            }
18365            if (allProtected) {
18366                // All safe!
18367                return;
18368            }
18369        }
18370
18371        // The vast majority of broadcasts sent from system internals
18372        // should be protected to avoid security holes, so yell loudly
18373        // to ensure we examine these cases.
18374        if (callerApp != null) {
18375            Log.wtf(TAG, "Sending non-protected broadcast " + action
18376                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
18377                    new Throwable());
18378        } else {
18379            Log.wtf(TAG, "Sending non-protected broadcast " + action
18380                            + " from system uid " + UserHandle.formatUid(callingUid)
18381                            + " pkg " + callerPackage,
18382                    new Throwable());
18383        }
18384    }
18385
18386    final int broadcastIntentLocked(ProcessRecord callerApp,
18387            String callerPackage, Intent intent, String resolvedType,
18388            IIntentReceiver resultTo, int resultCode, String resultData,
18389            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
18390            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
18391        intent = new Intent(intent);
18392
18393        // By default broadcasts do not go to stopped apps.
18394        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
18395
18396        // If we have not finished booting, don't allow this to launch new processes.
18397        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
18398            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18399        }
18400
18401        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
18402                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
18403                + " ordered=" + ordered + " userid=" + userId);
18404        if ((resultTo != null) && !ordered) {
18405            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
18406        }
18407
18408        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
18409                ALLOW_NON_FULL, "broadcast", callerPackage);
18410
18411        // Make sure that the user who is receiving this broadcast is running.
18412        // If not, we will just skip it. Make an exception for shutdown broadcasts
18413        // and upgrade steps.
18414
18415        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
18416            if ((callingUid != Process.SYSTEM_UID
18417                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
18418                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
18419                Slog.w(TAG, "Skipping broadcast of " + intent
18420                        + ": user " + userId + " is stopped");
18421                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
18422            }
18423        }
18424
18425        BroadcastOptions brOptions = null;
18426        if (bOptions != null) {
18427            brOptions = new BroadcastOptions(bOptions);
18428            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
18429                // See if the caller is allowed to do this.  Note we are checking against
18430                // the actual real caller (not whoever provided the operation as say a
18431                // PendingIntent), because that who is actually supplied the arguments.
18432                if (checkComponentPermission(
18433                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
18434                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
18435                        != PackageManager.PERMISSION_GRANTED) {
18436                    String msg = "Permission Denial: " + intent.getAction()
18437                            + " broadcast from " + callerPackage + " (pid=" + callingPid
18438                            + ", uid=" + callingUid + ")"
18439                            + " requires "
18440                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
18441                    Slog.w(TAG, msg);
18442                    throw new SecurityException(msg);
18443                }
18444            }
18445        }
18446
18447        // Verify that protected broadcasts are only being sent by system code,
18448        // and that system code is only sending protected broadcasts.
18449        final String action = intent.getAction();
18450        final boolean isProtectedBroadcast;
18451        try {
18452            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
18453        } catch (RemoteException e) {
18454            Slog.w(TAG, "Remote exception", e);
18455            return ActivityManager.BROADCAST_SUCCESS;
18456        }
18457
18458        final boolean isCallerSystem;
18459        switch (UserHandle.getAppId(callingUid)) {
18460            case Process.ROOT_UID:
18461            case Process.SYSTEM_UID:
18462            case Process.PHONE_UID:
18463            case Process.BLUETOOTH_UID:
18464            case Process.NFC_UID:
18465                isCallerSystem = true;
18466                break;
18467            default:
18468                isCallerSystem = (callerApp != null) && callerApp.persistent;
18469                break;
18470        }
18471
18472        // First line security check before anything else: stop non-system apps from
18473        // sending protected broadcasts.
18474        if (!isCallerSystem) {
18475            if (isProtectedBroadcast) {
18476                String msg = "Permission Denial: not allowed to send broadcast "
18477                        + action + " from pid="
18478                        + callingPid + ", uid=" + callingUid;
18479                Slog.w(TAG, msg);
18480                throw new SecurityException(msg);
18481
18482            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
18483                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
18484                // Special case for compatibility: we don't want apps to send this,
18485                // but historically it has not been protected and apps may be using it
18486                // to poke their own app widget.  So, instead of making it protected,
18487                // just limit it to the caller.
18488                if (callerPackage == null) {
18489                    String msg = "Permission Denial: not allowed to send broadcast "
18490                            + action + " from unknown caller.";
18491                    Slog.w(TAG, msg);
18492                    throw new SecurityException(msg);
18493                } else if (intent.getComponent() != null) {
18494                    // They are good enough to send to an explicit component...  verify
18495                    // it is being sent to the calling app.
18496                    if (!intent.getComponent().getPackageName().equals(
18497                            callerPackage)) {
18498                        String msg = "Permission Denial: not allowed to send broadcast "
18499                                + action + " to "
18500                                + intent.getComponent().getPackageName() + " from "
18501                                + callerPackage;
18502                        Slog.w(TAG, msg);
18503                        throw new SecurityException(msg);
18504                    }
18505                } else {
18506                    // Limit broadcast to their own package.
18507                    intent.setPackage(callerPackage);
18508                }
18509            }
18510        }
18511
18512        if (action != null) {
18513            if (getBackgroundLaunchBroadcasts().contains(action)) {
18514                if (DEBUG_BACKGROUND_CHECK) {
18515                    Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
18516                }
18517                intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
18518            }
18519
18520            switch (action) {
18521                case Intent.ACTION_UID_REMOVED:
18522                case Intent.ACTION_PACKAGE_REMOVED:
18523                case Intent.ACTION_PACKAGE_CHANGED:
18524                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18525                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18526                case Intent.ACTION_PACKAGES_SUSPENDED:
18527                case Intent.ACTION_PACKAGES_UNSUSPENDED:
18528                    // Handle special intents: if this broadcast is from the package
18529                    // manager about a package being removed, we need to remove all of
18530                    // its activities from the history stack.
18531                    if (checkComponentPermission(
18532                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
18533                            callingPid, callingUid, -1, true)
18534                            != PackageManager.PERMISSION_GRANTED) {
18535                        String msg = "Permission Denial: " + intent.getAction()
18536                                + " broadcast from " + callerPackage + " (pid=" + callingPid
18537                                + ", uid=" + callingUid + ")"
18538                                + " requires "
18539                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
18540                        Slog.w(TAG, msg);
18541                        throw new SecurityException(msg);
18542                    }
18543                    switch (action) {
18544                        case Intent.ACTION_UID_REMOVED:
18545                            final Bundle intentExtras = intent.getExtras();
18546                            final int uid = intentExtras != null
18547                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
18548                            if (uid >= 0) {
18549                                mBatteryStatsService.removeUid(uid);
18550                                mAppOpsService.uidRemoved(uid);
18551                            }
18552                            break;
18553                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18554                            // If resources are unavailable just force stop all those packages
18555                            // and flush the attribute cache as well.
18556                            String list[] =
18557                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18558                            if (list != null && list.length > 0) {
18559                                for (int i = 0; i < list.length; i++) {
18560                                    forceStopPackageLocked(list[i], -1, false, true, true,
18561                                            false, false, userId, "storage unmount");
18562                                }
18563                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18564                                sendPackageBroadcastLocked(
18565                                        ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
18566                                        list, userId);
18567                            }
18568                            break;
18569                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18570                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18571                            break;
18572                        case Intent.ACTION_PACKAGE_REMOVED:
18573                        case Intent.ACTION_PACKAGE_CHANGED:
18574                            Uri data = intent.getData();
18575                            String ssp;
18576                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
18577                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
18578                                final boolean replacing =
18579                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18580                                final boolean killProcess =
18581                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
18582                                final boolean fullUninstall = removed && !replacing;
18583                                if (removed) {
18584                                    if (killProcess) {
18585                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
18586                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
18587                                                false, true, true, false, fullUninstall, userId,
18588                                                removed ? "pkg removed" : "pkg changed");
18589                                    }
18590                                    final int cmd = killProcess
18591                                            ? ApplicationThreadConstants.PACKAGE_REMOVED
18592                                            : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
18593                                    sendPackageBroadcastLocked(cmd,
18594                                            new String[] {ssp}, userId);
18595                                    if (fullUninstall) {
18596                                        mAppOpsService.packageRemoved(
18597                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
18598
18599                                        // Remove all permissions granted from/to this package
18600                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
18601
18602                                        removeTasksByPackageNameLocked(ssp, userId);
18603
18604                                        // Hide the "unsupported display" dialog if necessary.
18605                                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18606                                                mUnsupportedDisplaySizeDialog.getPackageName())) {
18607                                            mUnsupportedDisplaySizeDialog.dismiss();
18608                                            mUnsupportedDisplaySizeDialog = null;
18609                                        }
18610                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
18611                                        mBatteryStatsService.notePackageUninstalled(ssp);
18612                                    }
18613                                } else {
18614                                    if (killProcess) {
18615                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
18616                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
18617                                                userId, ProcessList.INVALID_ADJ,
18618                                                false, true, true, false, "change " + ssp);
18619                                    }
18620                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
18621                                            intent.getStringArrayExtra(
18622                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
18623                                }
18624                            }
18625                            break;
18626                        case Intent.ACTION_PACKAGES_SUSPENDED:
18627                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
18628                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
18629                                    intent.getAction());
18630                            final String[] packageNames = intent.getStringArrayExtra(
18631                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
18632                            final int userHandle = intent.getIntExtra(
18633                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
18634
18635                            synchronized(ActivityManagerService.this) {
18636                                mRecentTasks.onPackagesSuspendedChanged(
18637                                        packageNames, suspended, userHandle);
18638                            }
18639                            break;
18640                    }
18641                    break;
18642                case Intent.ACTION_PACKAGE_REPLACED:
18643                {
18644                    final Uri data = intent.getData();
18645                    final String ssp;
18646                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18647                        final ApplicationInfo aInfo =
18648                                getPackageManagerInternalLocked().getApplicationInfo(
18649                                        ssp,
18650                                        userId);
18651                        if (aInfo == null) {
18652                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
18653                                    + " ssp=" + ssp + " data=" + data);
18654                            return ActivityManager.BROADCAST_SUCCESS;
18655                        }
18656                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
18657                        sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
18658                                new String[] {ssp}, userId);
18659                    }
18660                    break;
18661                }
18662                case Intent.ACTION_PACKAGE_ADDED:
18663                {
18664                    // Special case for adding a package: by default turn on compatibility mode.
18665                    Uri data = intent.getData();
18666                    String ssp;
18667                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18668                        final boolean replacing =
18669                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18670                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
18671
18672                        try {
18673                            ApplicationInfo ai = AppGlobals.getPackageManager().
18674                                    getApplicationInfo(ssp, 0, 0);
18675                            mBatteryStatsService.notePackageInstalled(ssp,
18676                                    ai != null ? ai.versionCode : 0);
18677                        } catch (RemoteException e) {
18678                        }
18679                    }
18680                    break;
18681                }
18682                case Intent.ACTION_PACKAGE_DATA_CLEARED:
18683                {
18684                    Uri data = intent.getData();
18685                    String ssp;
18686                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18687                        // Hide the "unsupported display" dialog if necessary.
18688                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18689                                mUnsupportedDisplaySizeDialog.getPackageName())) {
18690                            mUnsupportedDisplaySizeDialog.dismiss();
18691                            mUnsupportedDisplaySizeDialog = null;
18692                        }
18693                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
18694                    }
18695                    break;
18696                }
18697                case Intent.ACTION_TIMEZONE_CHANGED:
18698                    // If this is the time zone changed action, queue up a message that will reset
18699                    // the timezone of all currently running processes. This message will get
18700                    // queued up before the broadcast happens.
18701                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
18702                    break;
18703                case Intent.ACTION_TIME_CHANGED:
18704                    // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
18705                    // the tri-state value it may contain and "unknown".
18706                    // For convenience we re-use the Intent extra values.
18707                    final int NO_EXTRA_VALUE_FOUND = -1;
18708                    final int timeFormatPreferenceMsgValue = intent.getIntExtra(
18709                            Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
18710                            NO_EXTRA_VALUE_FOUND /* defaultValue */);
18711                    // Only send a message if the time preference is available.
18712                    if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
18713                        Message updateTimePreferenceMsg =
18714                                mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
18715                                        timeFormatPreferenceMsgValue, 0);
18716                        mHandler.sendMessage(updateTimePreferenceMsg);
18717                    }
18718                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18719                    synchronized (stats) {
18720                        stats.noteCurrentTimeChangedLocked();
18721                    }
18722                    break;
18723                case Intent.ACTION_CLEAR_DNS_CACHE:
18724                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
18725                    break;
18726                case Proxy.PROXY_CHANGE_ACTION:
18727                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
18728                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
18729                    break;
18730                case android.hardware.Camera.ACTION_NEW_PICTURE:
18731                case android.hardware.Camera.ACTION_NEW_VIDEO:
18732                    // These broadcasts are no longer allowed by the system, since they can
18733                    // cause significant thrashing at a crictical point (using the camera).
18734                    // Apps should use JobScehduler to monitor for media provider changes.
18735                    Slog.w(TAG, action + " no longer allowed; dropping from "
18736                            + UserHandle.formatUid(callingUid));
18737                    if (resultTo != null) {
18738                        final BroadcastQueue queue = broadcastQueueForIntent(intent);
18739                        try {
18740                            queue.performReceiveLocked(callerApp, resultTo, intent,
18741                                    Activity.RESULT_CANCELED, null, null,
18742                                    false, false, userId);
18743                        } catch (RemoteException e) {
18744                            Slog.w(TAG, "Failure ["
18745                                    + queue.mQueueName + "] sending broadcast result of "
18746                                    + intent, e);
18747
18748                        }
18749                    }
18750                    // Lie; we don't want to crash the app.
18751                    return ActivityManager.BROADCAST_SUCCESS;
18752                case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
18753                    mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
18754                    break;
18755            }
18756        }
18757
18758        // Add to the sticky list if requested.
18759        if (sticky) {
18760            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
18761                    callingPid, callingUid)
18762                    != PackageManager.PERMISSION_GRANTED) {
18763                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
18764                        + callingPid + ", uid=" + callingUid
18765                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18766                Slog.w(TAG, msg);
18767                throw new SecurityException(msg);
18768            }
18769            if (requiredPermissions != null && requiredPermissions.length > 0) {
18770                Slog.w(TAG, "Can't broadcast sticky intent " + intent
18771                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
18772                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
18773            }
18774            if (intent.getComponent() != null) {
18775                throw new SecurityException(
18776                        "Sticky broadcasts can't target a specific component");
18777            }
18778            // We use userId directly here, since the "all" target is maintained
18779            // as a separate set of sticky broadcasts.
18780            if (userId != UserHandle.USER_ALL) {
18781                // But first, if this is not a broadcast to all users, then
18782                // make sure it doesn't conflict with an existing broadcast to
18783                // all users.
18784                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
18785                        UserHandle.USER_ALL);
18786                if (stickies != null) {
18787                    ArrayList<Intent> list = stickies.get(intent.getAction());
18788                    if (list != null) {
18789                        int N = list.size();
18790                        int i;
18791                        for (i=0; i<N; i++) {
18792                            if (intent.filterEquals(list.get(i))) {
18793                                throw new IllegalArgumentException(
18794                                        "Sticky broadcast " + intent + " for user "
18795                                        + userId + " conflicts with existing global broadcast");
18796                            }
18797                        }
18798                    }
18799                }
18800            }
18801            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18802            if (stickies == null) {
18803                stickies = new ArrayMap<>();
18804                mStickyBroadcasts.put(userId, stickies);
18805            }
18806            ArrayList<Intent> list = stickies.get(intent.getAction());
18807            if (list == null) {
18808                list = new ArrayList<>();
18809                stickies.put(intent.getAction(), list);
18810            }
18811            final int stickiesCount = list.size();
18812            int i;
18813            for (i = 0; i < stickiesCount; i++) {
18814                if (intent.filterEquals(list.get(i))) {
18815                    // This sticky already exists, replace it.
18816                    list.set(i, new Intent(intent));
18817                    break;
18818                }
18819            }
18820            if (i >= stickiesCount) {
18821                list.add(new Intent(intent));
18822            }
18823        }
18824
18825        int[] users;
18826        if (userId == UserHandle.USER_ALL) {
18827            // Caller wants broadcast to go to all started users.
18828            users = mUserController.getStartedUserArrayLocked();
18829        } else {
18830            // Caller wants broadcast to go to one specific user.
18831            users = new int[] {userId};
18832        }
18833
18834        // Figure out who all will receive this broadcast.
18835        List receivers = null;
18836        List<BroadcastFilter> registeredReceivers = null;
18837        // Need to resolve the intent to interested receivers...
18838        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
18839                 == 0) {
18840            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
18841        }
18842        if (intent.getComponent() == null) {
18843            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
18844                // Query one target user at a time, excluding shell-restricted users
18845                for (int i = 0; i < users.length; i++) {
18846                    if (mUserController.hasUserRestriction(
18847                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
18848                        continue;
18849                    }
18850                    List<BroadcastFilter> registeredReceiversForUser =
18851                            mReceiverResolver.queryIntent(intent,
18852                                    resolvedType, false /*defaultOnly*/, users[i]);
18853                    if (registeredReceivers == null) {
18854                        registeredReceivers = registeredReceiversForUser;
18855                    } else if (registeredReceiversForUser != null) {
18856                        registeredReceivers.addAll(registeredReceiversForUser);
18857                    }
18858                }
18859            } else {
18860                registeredReceivers = mReceiverResolver.queryIntent(intent,
18861                        resolvedType, false /*defaultOnly*/, userId);
18862            }
18863        }
18864
18865        final boolean replacePending =
18866                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
18867
18868        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
18869                + " replacePending=" + replacePending);
18870
18871        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
18872        if (!ordered && NR > 0) {
18873            // If we are not serializing this broadcast, then send the
18874            // registered receivers separately so they don't wait for the
18875            // components to be launched.
18876            if (isCallerSystem) {
18877                checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18878                        isProtectedBroadcast, registeredReceivers);
18879            }
18880            final BroadcastQueue queue = broadcastQueueForIntent(intent);
18881            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18882                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
18883                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
18884                    resultExtras, ordered, sticky, false, userId);
18885            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
18886            final boolean replaced = replacePending
18887                    && (queue.replaceParallelBroadcastLocked(r) != null);
18888            // Note: We assume resultTo is null for non-ordered broadcasts.
18889            if (!replaced) {
18890                queue.enqueueParallelBroadcastLocked(r);
18891                queue.scheduleBroadcastsLocked();
18892            }
18893            registeredReceivers = null;
18894            NR = 0;
18895        }
18896
18897        // Merge into one list.
18898        int ir = 0;
18899        if (receivers != null) {
18900            // A special case for PACKAGE_ADDED: do not allow the package
18901            // being added to see this broadcast.  This prevents them from
18902            // using this as a back door to get run as soon as they are
18903            // installed.  Maybe in the future we want to have a special install
18904            // broadcast or such for apps, but we'd like to deliberately make
18905            // this decision.
18906            String skipPackages[] = null;
18907            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
18908                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
18909                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
18910                Uri data = intent.getData();
18911                if (data != null) {
18912                    String pkgName = data.getSchemeSpecificPart();
18913                    if (pkgName != null) {
18914                        skipPackages = new String[] { pkgName };
18915                    }
18916                }
18917            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18918                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18919            }
18920            if (skipPackages != null && (skipPackages.length > 0)) {
18921                for (String skipPackage : skipPackages) {
18922                    if (skipPackage != null) {
18923                        int NT = receivers.size();
18924                        for (int it=0; it<NT; it++) {
18925                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
18926                            if (curt.activityInfo.packageName.equals(skipPackage)) {
18927                                receivers.remove(it);
18928                                it--;
18929                                NT--;
18930                            }
18931                        }
18932                    }
18933                }
18934            }
18935
18936            int NT = receivers != null ? receivers.size() : 0;
18937            int it = 0;
18938            ResolveInfo curt = null;
18939            BroadcastFilter curr = null;
18940            while (it < NT && ir < NR) {
18941                if (curt == null) {
18942                    curt = (ResolveInfo)receivers.get(it);
18943                }
18944                if (curr == null) {
18945                    curr = registeredReceivers.get(ir);
18946                }
18947                if (curr.getPriority() >= curt.priority) {
18948                    // Insert this broadcast record into the final list.
18949                    receivers.add(it, curr);
18950                    ir++;
18951                    curr = null;
18952                    it++;
18953                    NT++;
18954                } else {
18955                    // Skip to the next ResolveInfo in the final list.
18956                    it++;
18957                    curt = null;
18958                }
18959            }
18960        }
18961        while (ir < NR) {
18962            if (receivers == null) {
18963                receivers = new ArrayList();
18964            }
18965            receivers.add(registeredReceivers.get(ir));
18966            ir++;
18967        }
18968
18969        if (isCallerSystem) {
18970            checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18971                    isProtectedBroadcast, receivers);
18972        }
18973
18974        if ((receivers != null && receivers.size() > 0)
18975                || resultTo != null) {
18976            BroadcastQueue queue = broadcastQueueForIntent(intent);
18977            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18978                    callerPackage, callingPid, callingUid, resolvedType,
18979                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18980                    resultData, resultExtras, ordered, sticky, false, userId);
18981
18982            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18983                    + ": prev had " + queue.mOrderedBroadcasts.size());
18984            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18985                    "Enqueueing broadcast " + r.intent.getAction());
18986
18987            final BroadcastRecord oldRecord =
18988                    replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
18989            if (oldRecord != null) {
18990                // Replaced, fire the result-to receiver.
18991                if (oldRecord.resultTo != null) {
18992                    final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
18993                    try {
18994                        oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
18995                                oldRecord.intent,
18996                                Activity.RESULT_CANCELED, null, null,
18997                                false, false, oldRecord.userId);
18998                    } catch (RemoteException e) {
18999                        Slog.w(TAG, "Failure ["
19000                                + queue.mQueueName + "] sending broadcast result of "
19001                                + intent, e);
19002
19003                    }
19004                }
19005            } else {
19006                queue.enqueueOrderedBroadcastLocked(r);
19007                queue.scheduleBroadcastsLocked();
19008            }
19009        } else {
19010            // There was nobody interested in the broadcast, but we still want to record
19011            // that it happened.
19012            if (intent.getComponent() == null && intent.getPackage() == null
19013                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19014                // This was an implicit broadcast... let's record it for posterity.
19015                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
19016            }
19017        }
19018
19019        return ActivityManager.BROADCAST_SUCCESS;
19020    }
19021
19022    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
19023            int skipCount, long dispatchTime) {
19024        final long now = SystemClock.elapsedRealtime();
19025        if (mCurBroadcastStats == null ||
19026                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
19027            mLastBroadcastStats = mCurBroadcastStats;
19028            if (mLastBroadcastStats != null) {
19029                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
19030                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
19031            }
19032            mCurBroadcastStats = new BroadcastStats();
19033        }
19034        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
19035    }
19036
19037    final Intent verifyBroadcastLocked(Intent intent) {
19038        // Refuse possible leaked file descriptors
19039        if (intent != null && intent.hasFileDescriptors() == true) {
19040            throw new IllegalArgumentException("File descriptors passed in Intent");
19041        }
19042
19043        int flags = intent.getFlags();
19044
19045        if (!mProcessesReady) {
19046            // if the caller really truly claims to know what they're doing, go
19047            // ahead and allow the broadcast without launching any receivers
19048            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
19049                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
19050            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19051                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
19052                        + " before boot completion");
19053                throw new IllegalStateException("Cannot broadcast before boot completed");
19054            }
19055        }
19056
19057        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
19058            throw new IllegalArgumentException(
19059                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
19060        }
19061
19062        if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
19063            switch (Binder.getCallingUid()) {
19064                case Process.ROOT_UID:
19065                case Process.SHELL_UID:
19066                    break;
19067                default:
19068                    Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
19069                            + Binder.getCallingUid());
19070                    intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
19071                    break;
19072            }
19073        }
19074
19075        return intent;
19076    }
19077
19078    public final int broadcastIntent(IApplicationThread caller,
19079            Intent intent, String resolvedType, IIntentReceiver resultTo,
19080            int resultCode, String resultData, Bundle resultExtras,
19081            String[] requiredPermissions, int appOp, Bundle bOptions,
19082            boolean serialized, boolean sticky, int userId) {
19083        enforceNotIsolatedCaller("broadcastIntent");
19084        synchronized(this) {
19085            intent = verifyBroadcastLocked(intent);
19086
19087            final ProcessRecord callerApp = getRecordForAppLocked(caller);
19088            final int callingPid = Binder.getCallingPid();
19089            final int callingUid = Binder.getCallingUid();
19090            final long origId = Binder.clearCallingIdentity();
19091            int res = broadcastIntentLocked(callerApp,
19092                    callerApp != null ? callerApp.info.packageName : null,
19093                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
19094                    requiredPermissions, appOp, bOptions, serialized, sticky,
19095                    callingPid, callingUid, userId);
19096            Binder.restoreCallingIdentity(origId);
19097            return res;
19098        }
19099    }
19100
19101
19102    int broadcastIntentInPackage(String packageName, int uid,
19103            Intent intent, String resolvedType, IIntentReceiver resultTo,
19104            int resultCode, String resultData, Bundle resultExtras,
19105            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
19106            int userId) {
19107        synchronized(this) {
19108            intent = verifyBroadcastLocked(intent);
19109
19110            final long origId = Binder.clearCallingIdentity();
19111            String[] requiredPermissions = requiredPermission == null ? null
19112                    : new String[] {requiredPermission};
19113            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
19114                    resultTo, resultCode, resultData, resultExtras,
19115                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
19116                    sticky, -1, uid, userId);
19117            Binder.restoreCallingIdentity(origId);
19118            return res;
19119        }
19120    }
19121
19122    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
19123        // Refuse possible leaked file descriptors
19124        if (intent != null && intent.hasFileDescriptors() == true) {
19125            throw new IllegalArgumentException("File descriptors passed in Intent");
19126        }
19127
19128        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19129                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
19130
19131        synchronized(this) {
19132            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
19133                    != PackageManager.PERMISSION_GRANTED) {
19134                String msg = "Permission Denial: unbroadcastIntent() from pid="
19135                        + Binder.getCallingPid()
19136                        + ", uid=" + Binder.getCallingUid()
19137                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19138                Slog.w(TAG, msg);
19139                throw new SecurityException(msg);
19140            }
19141            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19142            if (stickies != null) {
19143                ArrayList<Intent> list = stickies.get(intent.getAction());
19144                if (list != null) {
19145                    int N = list.size();
19146                    int i;
19147                    for (i=0; i<N; i++) {
19148                        if (intent.filterEquals(list.get(i))) {
19149                            list.remove(i);
19150                            break;
19151                        }
19152                    }
19153                    if (list.size() <= 0) {
19154                        stickies.remove(intent.getAction());
19155                    }
19156                }
19157                if (stickies.size() <= 0) {
19158                    mStickyBroadcasts.remove(userId);
19159                }
19160            }
19161        }
19162    }
19163
19164    void backgroundServicesFinishedLocked(int userId) {
19165        for (BroadcastQueue queue : mBroadcastQueues) {
19166            queue.backgroundServicesFinishedLocked(userId);
19167        }
19168    }
19169
19170    public void finishReceiver(IBinder who, int resultCode, String resultData,
19171            Bundle resultExtras, boolean resultAbort, int flags) {
19172        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
19173
19174        // Refuse possible leaked file descriptors
19175        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
19176            throw new IllegalArgumentException("File descriptors passed in Bundle");
19177        }
19178
19179        final long origId = Binder.clearCallingIdentity();
19180        try {
19181            boolean doNext = false;
19182            BroadcastRecord r;
19183
19184            synchronized(this) {
19185                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
19186                        ? mFgBroadcastQueue : mBgBroadcastQueue;
19187                r = queue.getMatchingOrderedReceiver(who);
19188                if (r != null) {
19189                    doNext = r.queue.finishReceiverLocked(r, resultCode,
19190                        resultData, resultExtras, resultAbort, true);
19191                }
19192            }
19193
19194            if (doNext) {
19195                r.queue.processNextBroadcast(false);
19196            }
19197            trimApplications();
19198        } finally {
19199            Binder.restoreCallingIdentity(origId);
19200        }
19201    }
19202
19203    // =========================================================
19204    // INSTRUMENTATION
19205    // =========================================================
19206
19207    public boolean startInstrumentation(ComponentName className,
19208            String profileFile, int flags, Bundle arguments,
19209            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
19210            int userId, String abiOverride) {
19211        enforceNotIsolatedCaller("startInstrumentation");
19212        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19213                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
19214        // Refuse possible leaked file descriptors
19215        if (arguments != null && arguments.hasFileDescriptors()) {
19216            throw new IllegalArgumentException("File descriptors passed in Bundle");
19217        }
19218
19219        synchronized(this) {
19220            InstrumentationInfo ii = null;
19221            ApplicationInfo ai = null;
19222            try {
19223                ii = mContext.getPackageManager().getInstrumentationInfo(
19224                    className, STOCK_PM_FLAGS);
19225                ai = AppGlobals.getPackageManager().getApplicationInfo(
19226                        ii.targetPackage, STOCK_PM_FLAGS, userId);
19227            } catch (PackageManager.NameNotFoundException e) {
19228            } catch (RemoteException e) {
19229            }
19230            if (ii == null) {
19231                reportStartInstrumentationFailureLocked(watcher, className,
19232                        "Unable to find instrumentation info for: " + className);
19233                return false;
19234            }
19235            if (ai == null) {
19236                reportStartInstrumentationFailureLocked(watcher, className,
19237                        "Unable to find instrumentation target package: " + ii.targetPackage);
19238                return false;
19239            }
19240            if (!ai.hasCode()) {
19241                reportStartInstrumentationFailureLocked(watcher, className,
19242                        "Instrumentation target has no code: " + ii.targetPackage);
19243                return false;
19244            }
19245
19246            int match = mContext.getPackageManager().checkSignatures(
19247                    ii.targetPackage, ii.packageName);
19248            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
19249                String msg = "Permission Denial: starting instrumentation "
19250                        + className + " from pid="
19251                        + Binder.getCallingPid()
19252                        + ", uid=" + Binder.getCallingPid()
19253                        + " not allowed because package " + ii.packageName
19254                        + " does not have a signature matching the target "
19255                        + ii.targetPackage;
19256                reportStartInstrumentationFailureLocked(watcher, className, msg);
19257                throw new SecurityException(msg);
19258            }
19259
19260            ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
19261            activeInstr.mClass = className;
19262            String defProcess = ai.processName;;
19263            if (ii.targetProcess == null) {
19264                activeInstr.mTargetProcesses = new String[]{ai.processName};
19265            } else if (ii.targetProcess.equals("*")) {
19266                activeInstr.mTargetProcesses = new String[0];
19267            } else {
19268                activeInstr.mTargetProcesses = ii.targetProcess.split(",");
19269                defProcess = activeInstr.mTargetProcesses[0];
19270            }
19271            activeInstr.mTargetInfo = ai;
19272            activeInstr.mProfileFile = profileFile;
19273            activeInstr.mArguments = arguments;
19274            activeInstr.mWatcher = watcher;
19275            activeInstr.mUiAutomationConnection = uiAutomationConnection;
19276            activeInstr.mResultClass = className;
19277
19278            final long origId = Binder.clearCallingIdentity();
19279            // Instrumentation can kill and relaunch even persistent processes
19280            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
19281                    "start instr");
19282            ProcessRecord app = addAppLocked(ai, defProcess, false, abiOverride);
19283            app.instr = activeInstr;
19284            activeInstr.mFinished = false;
19285            activeInstr.mRunningProcesses.add(app);
19286            if (!mActiveInstrumentation.contains(activeInstr)) {
19287                mActiveInstrumentation.add(activeInstr);
19288            }
19289            Binder.restoreCallingIdentity(origId);
19290        }
19291
19292        return true;
19293    }
19294
19295    /**
19296     * Report errors that occur while attempting to start Instrumentation.  Always writes the
19297     * error to the logs, but if somebody is watching, send the report there too.  This enables
19298     * the "am" command to report errors with more information.
19299     *
19300     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
19301     * @param cn The component name of the instrumentation.
19302     * @param report The error report.
19303     */
19304    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
19305            ComponentName cn, String report) {
19306        Slog.w(TAG, report);
19307        if (watcher != null) {
19308            Bundle results = new Bundle();
19309            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
19310            results.putString("Error", report);
19311            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
19312        }
19313    }
19314
19315    void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
19316        if (app.instr == null) {
19317            Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
19318            return;
19319        }
19320
19321        if (!app.instr.mFinished && results != null) {
19322            if (app.instr.mCurResults == null) {
19323                app.instr.mCurResults = new Bundle(results);
19324            } else {
19325                app.instr.mCurResults.putAll(results);
19326            }
19327        }
19328    }
19329
19330    public void addInstrumentationResults(IApplicationThread target, Bundle results) {
19331        int userId = UserHandle.getCallingUserId();
19332        // Refuse possible leaked file descriptors
19333        if (results != null && results.hasFileDescriptors()) {
19334            throw new IllegalArgumentException("File descriptors passed in Intent");
19335        }
19336
19337        synchronized(this) {
19338            ProcessRecord app = getRecordForAppLocked(target);
19339            if (app == null) {
19340                Slog.w(TAG, "addInstrumentationResults: no app for " + target);
19341                return;
19342            }
19343            final long origId = Binder.clearCallingIdentity();
19344            addInstrumentationResultsLocked(app, results);
19345            Binder.restoreCallingIdentity(origId);
19346        }
19347    }
19348
19349    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
19350        if (app.instr == null) {
19351            Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
19352            return;
19353        }
19354
19355        if (!app.instr.mFinished) {
19356            if (app.instr.mWatcher != null) {
19357                Bundle finalResults = app.instr.mCurResults;
19358                if (finalResults != null) {
19359                    if (app.instr.mCurResults != null && results != null) {
19360                        finalResults.putAll(results);
19361                    }
19362                } else {
19363                    finalResults = results;
19364                }
19365                mInstrumentationReporter.reportFinished(app.instr.mWatcher,
19366                        app.instr.mClass, resultCode, finalResults);
19367            }
19368
19369            // Can't call out of the system process with a lock held, so post a message.
19370            if (app.instr.mUiAutomationConnection != null) {
19371                mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
19372                        app.instr.mUiAutomationConnection).sendToTarget();
19373            }
19374            app.instr.mFinished = true;
19375        }
19376
19377        app.instr.removeProcess(app);
19378        app.instr = null;
19379
19380        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
19381                "finished inst");
19382    }
19383
19384    public void finishInstrumentation(IApplicationThread target,
19385            int resultCode, Bundle results) {
19386        int userId = UserHandle.getCallingUserId();
19387        // Refuse possible leaked file descriptors
19388        if (results != null && results.hasFileDescriptors()) {
19389            throw new IllegalArgumentException("File descriptors passed in Intent");
19390        }
19391
19392        synchronized(this) {
19393            ProcessRecord app = getRecordForAppLocked(target);
19394            if (app == null) {
19395                Slog.w(TAG, "finishInstrumentation: no app for " + target);
19396                return;
19397            }
19398            final long origId = Binder.clearCallingIdentity();
19399            finishInstrumentationLocked(app, resultCode, results);
19400            Binder.restoreCallingIdentity(origId);
19401        }
19402    }
19403
19404    // =========================================================
19405    // CONFIGURATION
19406    // =========================================================
19407
19408    public ConfigurationInfo getDeviceConfigurationInfo() {
19409        ConfigurationInfo config = new ConfigurationInfo();
19410        synchronized (this) {
19411            final Configuration globalConfig = getGlobalConfiguration();
19412            config.reqTouchScreen = globalConfig.touchscreen;
19413            config.reqKeyboardType = globalConfig.keyboard;
19414            config.reqNavigation = globalConfig.navigation;
19415            if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
19416                    || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
19417                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
19418            }
19419            if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
19420                    && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
19421                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
19422            }
19423            config.reqGlEsVersion = GL_ES_VERSION;
19424        }
19425        return config;
19426    }
19427
19428    ActivityStack getFocusedStack() {
19429        return mStackSupervisor.getFocusedStack();
19430    }
19431
19432    @Override
19433    public int getFocusedStackId() throws RemoteException {
19434        ActivityStack focusedStack = getFocusedStack();
19435        if (focusedStack != null) {
19436            return focusedStack.getStackId();
19437        }
19438        return -1;
19439    }
19440
19441    public Configuration getConfiguration() {
19442        Configuration ci;
19443        synchronized(this) {
19444            ci = new Configuration(getGlobalConfiguration());
19445            ci.userSetLocale = false;
19446        }
19447        return ci;
19448    }
19449
19450    @Override
19451    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
19452        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
19453        synchronized (this) {
19454            mSuppressResizeConfigChanges = suppress;
19455        }
19456    }
19457
19458    @Override
19459    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
19460        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
19461        if (StackId.isHomeOrRecentsStack(fromStackId)) {
19462            throw new IllegalArgumentException("You can't move tasks from the home/recents stack.");
19463        }
19464        synchronized (this) {
19465            final long origId = Binder.clearCallingIdentity();
19466            try {
19467                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
19468            } finally {
19469                Binder.restoreCallingIdentity(origId);
19470            }
19471        }
19472    }
19473
19474    @Override
19475    public void updatePersistentConfiguration(Configuration values) {
19476        enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
19477        enforceWriteSettingsPermission("updatePersistentConfiguration()");
19478        if (values == null) {
19479            throw new NullPointerException("Configuration must not be null");
19480        }
19481
19482        int userId = UserHandle.getCallingUserId();
19483
19484        synchronized(this) {
19485            updatePersistentConfigurationLocked(values, userId);
19486        }
19487    }
19488
19489    private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
19490        final long origId = Binder.clearCallingIdentity();
19491        try {
19492            updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
19493        } finally {
19494            Binder.restoreCallingIdentity(origId);
19495        }
19496    }
19497
19498    private void updateFontScaleIfNeeded(@UserIdInt int userId) {
19499        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
19500                FONT_SCALE, 1.0f, userId);
19501
19502        synchronized (this) {
19503            if (getGlobalConfiguration().fontScale == scaleFactor) {
19504                return;
19505            }
19506
19507            final Configuration configuration
19508                    = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
19509            configuration.fontScale = scaleFactor;
19510            updatePersistentConfigurationLocked(configuration, userId);
19511        }
19512    }
19513
19514    private void enforceWriteSettingsPermission(String func) {
19515        int uid = Binder.getCallingUid();
19516        if (uid == Process.ROOT_UID) {
19517            return;
19518        }
19519
19520        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
19521                Settings.getPackageNameForUid(mContext, uid), false)) {
19522            return;
19523        }
19524
19525        String msg = "Permission Denial: " + func + " from pid="
19526                + Binder.getCallingPid()
19527                + ", uid=" + uid
19528                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
19529        Slog.w(TAG, msg);
19530        throw new SecurityException(msg);
19531    }
19532
19533    @Override
19534    public boolean updateConfiguration(Configuration values) {
19535        enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
19536
19537        synchronized(this) {
19538            if (values == null && mWindowManager != null) {
19539                // sentinel: fetch the current configuration from the window manager
19540                values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
19541            }
19542
19543            if (mWindowManager != null) {
19544                // Update OOM levels based on display size.
19545                mProcessList.applyDisplaySize(mWindowManager);
19546            }
19547
19548            final long origId = Binder.clearCallingIdentity();
19549            try {
19550                if (values != null) {
19551                    Settings.System.clearConfiguration(values);
19552                }
19553                updateConfigurationLocked(values, null, false, false /* persistent */,
19554                        UserHandle.USER_NULL, false /* deferResume */,
19555                        mTmpUpdateConfigurationResult);
19556                return mTmpUpdateConfigurationResult.changes != 0;
19557            } finally {
19558                Binder.restoreCallingIdentity(origId);
19559            }
19560        }
19561    }
19562
19563    void updateUserConfigurationLocked() {
19564        final Configuration configuration = new Configuration(getGlobalConfiguration());
19565        final int currentUserId = mUserController.getCurrentUserIdLocked();
19566        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
19567                currentUserId, Settings.System.canWrite(mContext));
19568        updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
19569                false /* persistent */, currentUserId, false /* deferResume */);
19570    }
19571
19572    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19573            boolean initLocale) {
19574        return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
19575    }
19576
19577    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19578            boolean initLocale, boolean deferResume) {
19579        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
19580        return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
19581                UserHandle.USER_NULL, deferResume);
19582    }
19583
19584    // To cache the list of supported system locales
19585    private String[] mSupportedSystemLocales = null;
19586
19587    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19588            boolean initLocale, boolean persistent, int userId, boolean deferResume) {
19589        return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
19590                deferResume, null /* result */);
19591    }
19592
19593    /**
19594     * Do either or both things: (1) change the current configuration, and (2)
19595     * make sure the given activity is running with the (now) current
19596     * configuration.  Returns true if the activity has been left running, or
19597     * false if <var>starting</var> is being destroyed to match the new
19598     * configuration.
19599     *
19600     * @param userId is only used when persistent parameter is set to true to persist configuration
19601     *               for that particular user
19602     */
19603    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19604            boolean initLocale, boolean persistent, int userId, boolean deferResume,
19605            UpdateConfigurationResult result) {
19606        int changes = 0;
19607        boolean kept = true;
19608
19609        if (mWindowManager != null) {
19610            mWindowManager.deferSurfaceLayout();
19611        }
19612        try {
19613            if (values != null) {
19614                changes = updateGlobalConfiguration(values, initLocale, persistent, userId,
19615                        deferResume);
19616            }
19617
19618            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
19619        } finally {
19620            if (mWindowManager != null) {
19621                mWindowManager.continueSurfaceLayout();
19622            }
19623        }
19624
19625        if (result != null) {
19626            result.changes = changes;
19627            result.activityRelaunched = !kept;
19628        }
19629        return kept;
19630    }
19631
19632    /** Update default (global) configuration and notify listeners about changes. */
19633    private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale,
19634            boolean persistent, int userId, boolean deferResume) {
19635        mTempConfig.setTo(getGlobalConfiguration());
19636        final int changes = mTempConfig.updateFrom(values);
19637        if (changes == 0) {
19638            return 0;
19639        }
19640
19641        if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
19642                "Updating global configuration to: " + values);
19643
19644        EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
19645
19646        if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
19647            final LocaleList locales = values.getLocales();
19648            int bestLocaleIndex = 0;
19649            if (locales.size() > 1) {
19650                if (mSupportedSystemLocales == null) {
19651                    mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
19652                }
19653                bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
19654            }
19655            SystemProperties.set("persist.sys.locale",
19656                    locales.get(bestLocaleIndex).toLanguageTag());
19657            LocaleList.setDefault(locales, bestLocaleIndex);
19658            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
19659                    locales.get(bestLocaleIndex)));
19660        }
19661
19662        mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
19663        mTempConfig.seq = mConfigurationSeq;
19664
19665        // Update stored global config and notify everyone about the change.
19666        mStackSupervisor.onConfigurationChanged(mTempConfig);
19667
19668        Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
19669        // TODO(multi-display): Update UsageEvents#Event to include displayId.
19670        mUsageStatsService.reportConfigurationChange(mTempConfig,
19671                mUserController.getCurrentUserIdLocked());
19672
19673        // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
19674        mShowDialogs = shouldShowDialogs(mTempConfig, mInVrMode);
19675
19676        AttributeCache ac = AttributeCache.instance();
19677        if (ac != null) {
19678            ac.updateConfiguration(mTempConfig);
19679        }
19680
19681        // Make sure all resources in our process are updated right now, so that anyone who is going
19682        // to retrieve resource values after we return will be sure to get the new ones. This is
19683        // especially important during boot, where the first config change needs to guarantee all
19684        // resources have that config before following boot code is executed.
19685        mSystemThread.applyConfigurationToResources(mTempConfig);
19686
19687        // We need another copy of global config because we're scheduling some calls instead of
19688        // running them in place. We need to be sure that object we send will be handled unchanged.
19689        final Configuration configCopy = new Configuration(mTempConfig);
19690        if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
19691            Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
19692            msg.obj = configCopy;
19693            msg.arg1 = userId;
19694            mHandler.sendMessage(msg);
19695        }
19696
19697        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19698            ProcessRecord app = mLruProcesses.get(i);
19699            try {
19700                if (app.thread != null) {
19701                    if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
19702                            + app.processName + " new config " + configCopy);
19703                    app.thread.scheduleConfigurationChanged(configCopy);
19704                }
19705            } catch (Exception e) {
19706            }
19707        }
19708
19709        Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
19710        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
19711                | Intent.FLAG_RECEIVER_FOREGROUND);
19712        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
19713                AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID,
19714                UserHandle.USER_ALL);
19715        if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
19716            intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
19717            intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
19718                    | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
19719            if (initLocale || !mProcessesReady) {
19720                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19721            }
19722            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
19723                    AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID,
19724                    UserHandle.USER_ALL);
19725        }
19726
19727        // Override configuration of the default display duplicates global config, so we need to
19728        // update it also. This will also notify WindowManager about changes.
19729        performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
19730                DEFAULT_DISPLAY);
19731
19732        return changes;
19733    }
19734
19735    @Override
19736    public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
19737        enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
19738
19739        synchronized (this) {
19740            // Check if display is initialized in AM.
19741            if (!mStackSupervisor.isDisplayAdded(displayId)) {
19742                // Call might come when display is not yet added or has already been removed.
19743                if (DEBUG_CONFIGURATION) {
19744                    Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
19745                            + displayId);
19746                }
19747                return false;
19748            }
19749
19750            if (values == null && mWindowManager != null) {
19751                // sentinel: fetch the current configuration from the window manager
19752                values = mWindowManager.computeNewConfiguration(displayId);
19753            }
19754
19755            if (mWindowManager != null) {
19756                // Update OOM levels based on display size.
19757                mProcessList.applyDisplaySize(mWindowManager);
19758            }
19759
19760            final long origId = Binder.clearCallingIdentity();
19761            try {
19762                if (values != null) {
19763                    Settings.System.clearConfiguration(values);
19764                }
19765                updateDisplayOverrideConfigurationLocked(values, null /* starting */,
19766                        false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
19767                return mTmpUpdateConfigurationResult.changes != 0;
19768            } finally {
19769                Binder.restoreCallingIdentity(origId);
19770            }
19771        }
19772    }
19773
19774    boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
19775            boolean deferResume, int displayId) {
19776        return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
19777                displayId, null /* result */);
19778    }
19779
19780    /**
19781     * Updates override configuration specific for the selected display. If no config is provided,
19782     * new one will be computed in WM based on current display info.
19783     */
19784    private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
19785            ActivityRecord starting, boolean deferResume, int displayId,
19786            UpdateConfigurationResult result) {
19787        int changes = 0;
19788        boolean kept = true;
19789
19790        if (mWindowManager != null) {
19791            mWindowManager.deferSurfaceLayout();
19792        }
19793        try {
19794            if (values != null) {
19795                if (displayId == DEFAULT_DISPLAY) {
19796                    // Override configuration of the default display duplicates global config, so
19797                    // we're calling global config update instead for default display. It will also
19798                    // apply the correct override config.
19799                    changes = updateGlobalConfiguration(values, false /* initLocale */,
19800                            false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
19801                } else {
19802                    changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
19803                }
19804            }
19805
19806            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
19807        } finally {
19808            if (mWindowManager != null) {
19809                mWindowManager.continueSurfaceLayout();
19810            }
19811        }
19812
19813        if (result != null) {
19814            result.changes = changes;
19815            result.activityRelaunched = !kept;
19816        }
19817        return kept;
19818    }
19819
19820    private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
19821            int displayId) {
19822        mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
19823        final int changes = mTempConfig.updateFrom(values);
19824        if (changes == 0) {
19825            return 0;
19826        }
19827
19828        Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " " + mTempConfig
19829                + " for displayId=" + displayId);
19830        mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
19831
19832        final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
19833        if (isDensityChange && displayId == DEFAULT_DISPLAY) {
19834            // Reset the unsupported display size dialog.
19835            mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
19836
19837            killAllBackgroundProcessesExcept(N, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
19838        }
19839
19840        // Update the configuration with WM first and check if any of the stacks need to be resized
19841        // due to the configuration change. If so, resize the stacks now and do any relaunches if
19842        // necessary. This way we don't need to relaunch again afterwards in
19843        // ensureActivityConfigurationLocked().
19844        if (mWindowManager != null) {
19845            final int[] resizedStacks =
19846                    mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
19847            if (resizedStacks != null) {
19848                for (int stackId : resizedStacks) {
19849                    resizeStackWithBoundsFromWindowManager(stackId, deferResume);
19850                }
19851            }
19852        }
19853
19854        return changes;
19855    }
19856
19857    /** Applies latest configuration and/or visibility updates if needed. */
19858    private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
19859        boolean kept = true;
19860        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
19861        // mainStack is null during startup.
19862        if (mainStack != null) {
19863            if (changes != 0 && starting == null) {
19864                // If the configuration changed, and the caller is not already
19865                // in the process of starting an activity, then find the top
19866                // activity to check if its configuration needs to change.
19867                starting = mainStack.topRunningActivityLocked();
19868            }
19869
19870            if (starting != null) {
19871                kept = starting.ensureActivityConfigurationLocked(changes,
19872                        false /* preserveWindow */);
19873                // And we need to make sure at this point that all other activities
19874                // are made visible with the correct configuration.
19875                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
19876                        !PRESERVE_WINDOWS);
19877            }
19878        }
19879
19880        return kept;
19881    }
19882
19883    /** Helper method that requests bounds from WM and applies them to stack. */
19884    private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
19885        final Rect newStackBounds = new Rect();
19886        final Rect newTempTaskBounds = new Rect();
19887        mStackSupervisor.getStack(stackId).getBoundsForNewConfiguration(newStackBounds,
19888                newTempTaskBounds);
19889        mStackSupervisor.resizeStackLocked(
19890                stackId, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
19891                !newTempTaskBounds.isEmpty() ? newTempTaskBounds : null /* tempTaskBounds */,
19892                null /* tempTaskInsetBounds */, false /* preserveWindows */,
19893                false /* allowResizeInDockedMode */, deferResume);
19894    }
19895
19896    /**
19897     * Decide based on the configuration whether we should show the ANR,
19898     * crash, etc dialogs.  The idea is that if there is no affordance to
19899     * press the on-screen buttons, or the user experience would be more
19900     * greatly impacted than the crash itself, we shouldn't show the dialog.
19901     *
19902     * A thought: SystemUI might also want to get told about this, the Power
19903     * dialog / global actions also might want different behaviors.
19904     */
19905    private static boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
19906        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
19907                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
19908                                   && config.navigation == Configuration.NAVIGATION_NONAV);
19909        int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
19910        final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
19911                && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE))
19912                && modeType != Configuration.UI_MODE_TYPE_TELEVISION);
19913        return inputMethodExists && uiModeSupportsDialogs && !inVrMode;
19914    }
19915
19916    @Override
19917    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
19918        synchronized (this) {
19919            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
19920            if (srec != null) {
19921                return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
19922            }
19923        }
19924        return false;
19925    }
19926
19927    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
19928            Intent resultData) {
19929
19930        synchronized (this) {
19931            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
19932            if (r != null) {
19933                return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
19934            }
19935            return false;
19936        }
19937    }
19938
19939    public int getLaunchedFromUid(IBinder activityToken) {
19940        ActivityRecord srec;
19941        synchronized (this) {
19942            srec = ActivityRecord.forTokenLocked(activityToken);
19943        }
19944        if (srec == null) {
19945            return -1;
19946        }
19947        return srec.launchedFromUid;
19948    }
19949
19950    public String getLaunchedFromPackage(IBinder activityToken) {
19951        ActivityRecord srec;
19952        synchronized (this) {
19953            srec = ActivityRecord.forTokenLocked(activityToken);
19954        }
19955        if (srec == null) {
19956            return null;
19957        }
19958        return srec.launchedFromPackage;
19959    }
19960
19961    // =========================================================
19962    // LIFETIME MANAGEMENT
19963    // =========================================================
19964
19965    // Returns whether the app is receiving broadcast.
19966    // If receiving, fetch all broadcast queues which the app is
19967    // the current [or imminent] receiver on.
19968    private boolean isReceivingBroadcastLocked(ProcessRecord app,
19969            ArraySet<BroadcastQueue> receivingQueues) {
19970        if (!app.curReceivers.isEmpty()) {
19971            for (BroadcastRecord r : app.curReceivers) {
19972                receivingQueues.add(r.queue);
19973            }
19974            return true;
19975        }
19976
19977        // It's not the current receiver, but it might be starting up to become one
19978        for (BroadcastQueue queue : mBroadcastQueues) {
19979            final BroadcastRecord r = queue.mPendingBroadcast;
19980            if (r != null && r.curApp == app) {
19981                // found it; report which queue it's in
19982                receivingQueues.add(queue);
19983            }
19984        }
19985
19986        return !receivingQueues.isEmpty();
19987    }
19988
19989    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
19990            int targetUid, ComponentName targetComponent, String targetProcess) {
19991        if (!mTrackingAssociations) {
19992            return null;
19993        }
19994        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19995                = mAssociations.get(targetUid);
19996        if (components == null) {
19997            components = new ArrayMap<>();
19998            mAssociations.put(targetUid, components);
19999        }
20000        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20001        if (sourceUids == null) {
20002            sourceUids = new SparseArray<>();
20003            components.put(targetComponent, sourceUids);
20004        }
20005        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20006        if (sourceProcesses == null) {
20007            sourceProcesses = new ArrayMap<>();
20008            sourceUids.put(sourceUid, sourceProcesses);
20009        }
20010        Association ass = sourceProcesses.get(sourceProcess);
20011        if (ass == null) {
20012            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
20013                    targetProcess);
20014            sourceProcesses.put(sourceProcess, ass);
20015        }
20016        ass.mCount++;
20017        ass.mNesting++;
20018        if (ass.mNesting == 1) {
20019            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
20020            ass.mLastState = sourceState;
20021        }
20022        return ass;
20023    }
20024
20025    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
20026            ComponentName targetComponent) {
20027        if (!mTrackingAssociations) {
20028            return;
20029        }
20030        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20031                = mAssociations.get(targetUid);
20032        if (components == null) {
20033            return;
20034        }
20035        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20036        if (sourceUids == null) {
20037            return;
20038        }
20039        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20040        if (sourceProcesses == null) {
20041            return;
20042        }
20043        Association ass = sourceProcesses.get(sourceProcess);
20044        if (ass == null || ass.mNesting <= 0) {
20045            return;
20046        }
20047        ass.mNesting--;
20048        if (ass.mNesting == 0) {
20049            long uptime = SystemClock.uptimeMillis();
20050            ass.mTime += uptime - ass.mStartTime;
20051            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20052                    += uptime - ass.mLastStateUptime;
20053            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
20054        }
20055    }
20056
20057    private void noteUidProcessState(final int uid, final int state) {
20058        mBatteryStatsService.noteUidProcessState(uid, state);
20059        if (mTrackingAssociations) {
20060            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
20061                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
20062                        = mAssociations.valueAt(i1);
20063                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
20064                    SparseArray<ArrayMap<String, Association>> sourceUids
20065                            = targetComponents.valueAt(i2);
20066                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
20067                    if (sourceProcesses != null) {
20068                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
20069                            Association ass = sourceProcesses.valueAt(i4);
20070                            if (ass.mNesting >= 1) {
20071                                // currently associated
20072                                long uptime = SystemClock.uptimeMillis();
20073                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20074                                        += uptime - ass.mLastStateUptime;
20075                                ass.mLastState = state;
20076                                ass.mLastStateUptime = uptime;
20077                            }
20078                        }
20079                    }
20080                }
20081            }
20082        }
20083    }
20084
20085    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
20086            boolean doingAll, long now) {
20087        if (mAdjSeq == app.adjSeq) {
20088            // This adjustment has already been computed.
20089            return app.curRawAdj;
20090        }
20091
20092        if (app.thread == null) {
20093            app.adjSeq = mAdjSeq;
20094            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20095            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20096            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
20097        }
20098
20099        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
20100        app.adjSource = null;
20101        app.adjTarget = null;
20102        app.empty = false;
20103        app.cached = false;
20104
20105        final int activitiesSize = app.activities.size();
20106
20107        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
20108            // The max adjustment doesn't allow this app to be anything
20109            // below foreground, so it is not worth doing work for it.
20110            app.adjType = "fixed";
20111            app.adjSeq = mAdjSeq;
20112            app.curRawAdj = app.maxAdj;
20113            app.foregroundActivities = false;
20114            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20115            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
20116            // System processes can do UI, and when they do we want to have
20117            // them trim their memory after the user leaves the UI.  To
20118            // facilitate this, here we need to determine whether or not it
20119            // is currently showing UI.
20120            app.systemNoUi = true;
20121            if (app == TOP_APP) {
20122                app.systemNoUi = false;
20123                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20124                app.adjType = "pers-top-activity";
20125            } else if (app.hasTopUi) {
20126                app.systemNoUi = false;
20127                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20128                app.adjType = "pers-top-ui";
20129            } else if (activitiesSize > 0) {
20130                for (int j = 0; j < activitiesSize; j++) {
20131                    final ActivityRecord r = app.activities.get(j);
20132                    if (r.visible) {
20133                        app.systemNoUi = false;
20134                    }
20135                }
20136            }
20137            if (!app.systemNoUi) {
20138                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
20139            }
20140            return (app.curAdj=app.maxAdj);
20141        }
20142
20143        app.systemNoUi = false;
20144
20145        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
20146
20147        // Determine the importance of the process, starting with most
20148        // important to least, and assign an appropriate OOM adjustment.
20149        int adj;
20150        int schedGroup;
20151        int procState;
20152        boolean foregroundActivities = false;
20153        mTmpBroadcastQueue.clear();
20154        if (app == TOP_APP) {
20155            // The last app on the list is the foreground app.
20156            adj = ProcessList.FOREGROUND_APP_ADJ;
20157            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20158            app.adjType = "top-activity";
20159            foregroundActivities = true;
20160            procState = PROCESS_STATE_CUR_TOP;
20161        } else if (app.instr != null) {
20162            // Don't want to kill running instrumentation.
20163            adj = ProcessList.FOREGROUND_APP_ADJ;
20164            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20165            app.adjType = "instrumentation";
20166            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
20167        } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
20168            // An app that is currently receiving a broadcast also
20169            // counts as being in the foreground for OOM killer purposes.
20170            // It's placed in a sched group based on the nature of the
20171            // broadcast as reflected by which queue it's active in.
20172            adj = ProcessList.FOREGROUND_APP_ADJ;
20173            schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
20174                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20175            app.adjType = "broadcast";
20176            procState = ActivityManager.PROCESS_STATE_RECEIVER;
20177        } else if (app.executingServices.size() > 0) {
20178            // An app that is currently executing a service callback also
20179            // counts as being in the foreground.
20180            adj = ProcessList.FOREGROUND_APP_ADJ;
20181            schedGroup = app.execServicesFg ?
20182                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20183            app.adjType = "exec-service";
20184            procState = ActivityManager.PROCESS_STATE_SERVICE;
20185            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
20186        } else {
20187            // As far as we know the process is empty.  We may change our mind later.
20188            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20189            // At this point we don't actually know the adjustment.  Use the cached adj
20190            // value that the caller wants us to.
20191            adj = cachedAdj;
20192            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20193            app.cached = true;
20194            app.empty = true;
20195            app.adjType = "cch-empty";
20196        }
20197
20198        // Examine all activities if not already foreground.
20199        if (!foregroundActivities && activitiesSize > 0) {
20200            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
20201            for (int j = 0; j < activitiesSize; j++) {
20202                final ActivityRecord r = app.activities.get(j);
20203                if (r.app != app) {
20204                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
20205                            + " instead of expected " + app);
20206                    if (r.app == null || (r.app.uid == app.uid)) {
20207                        // Only fix things up when they look sane
20208                        r.app = app;
20209                    } else {
20210                        continue;
20211                    }
20212                }
20213                if (r.visible) {
20214                    // App has a visible activity; only upgrade adjustment.
20215                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
20216                        adj = ProcessList.VISIBLE_APP_ADJ;
20217                        app.adjType = "visible";
20218                    }
20219                    if (procState > PROCESS_STATE_CUR_TOP) {
20220                        procState = PROCESS_STATE_CUR_TOP;
20221                    }
20222                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20223                    app.cached = false;
20224                    app.empty = false;
20225                    foregroundActivities = true;
20226                    if (r.task != null && minLayer > 0) {
20227                        final int layer = r.task.mLayerRank;
20228                        if (layer >= 0 && minLayer > layer) {
20229                            minLayer = layer;
20230                        }
20231                    }
20232                    break;
20233                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
20234                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20235                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20236                        app.adjType = "pausing";
20237                    }
20238                    if (procState > PROCESS_STATE_CUR_TOP) {
20239                        procState = PROCESS_STATE_CUR_TOP;
20240                    }
20241                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20242                    app.cached = false;
20243                    app.empty = false;
20244                    foregroundActivities = true;
20245                } else if (r.state == ActivityState.STOPPING) {
20246                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20247                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20248                        app.adjType = "stopping";
20249                    }
20250                    // For the process state, we will at this point consider the
20251                    // process to be cached.  It will be cached either as an activity
20252                    // or empty depending on whether the activity is finishing.  We do
20253                    // this so that we can treat the process as cached for purposes of
20254                    // memory trimming (determing current memory level, trim command to
20255                    // send to process) since there can be an arbitrary number of stopping
20256                    // processes and they should soon all go into the cached state.
20257                    if (!r.finishing) {
20258                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
20259                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
20260                        }
20261                    }
20262                    app.cached = false;
20263                    app.empty = false;
20264                    foregroundActivities = true;
20265                } else {
20266                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
20267                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
20268                        app.adjType = "cch-act";
20269                    }
20270                }
20271            }
20272            if (adj == ProcessList.VISIBLE_APP_ADJ) {
20273                adj += minLayer;
20274            }
20275        }
20276
20277        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
20278                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
20279            if (app.foregroundServices) {
20280                // The user is aware of this app, so make it visible.
20281                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20282                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
20283                app.cached = false;
20284                app.adjType = "fg-service";
20285                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20286            } else if (app.forcingToForeground != null) {
20287                // The user is aware of this app, so make it visible.
20288                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20289                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20290                app.cached = false;
20291                app.adjType = "force-fg";
20292                app.adjSource = app.forcingToForeground;
20293                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20294            } else if (app.hasOverlayUi) {
20295                // The process is display an overlay UI.
20296                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20297                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20298                app.cached = false;
20299                app.adjType = "has-overlay-ui";
20300                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20301            }
20302        }
20303
20304        if (app == mHeavyWeightProcess) {
20305            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
20306                // We don't want to kill the current heavy-weight process.
20307                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
20308                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20309                app.cached = false;
20310                app.adjType = "heavy";
20311            }
20312            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20313                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
20314            }
20315        }
20316
20317        if (app == mHomeProcess) {
20318            if (adj > ProcessList.HOME_APP_ADJ) {
20319                // This process is hosting what we currently consider to be the
20320                // home app, so we don't want to let it go into the background.
20321                adj = ProcessList.HOME_APP_ADJ;
20322                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20323                app.cached = false;
20324                app.adjType = "home";
20325            }
20326            if (procState > ActivityManager.PROCESS_STATE_HOME) {
20327                procState = ActivityManager.PROCESS_STATE_HOME;
20328            }
20329        }
20330
20331        if (app == mPreviousProcess && app.activities.size() > 0) {
20332            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
20333                // This was the previous process that showed UI to the user.
20334                // We want to try to keep it around more aggressively, to give
20335                // a good experience around switching between two apps.
20336                adj = ProcessList.PREVIOUS_APP_ADJ;
20337                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20338                app.cached = false;
20339                app.adjType = "previous";
20340            }
20341            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
20342                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
20343            }
20344        }
20345
20346        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
20347                + " reason=" + app.adjType);
20348
20349        // By default, we use the computed adjustment.  It may be changed if
20350        // there are applications dependent on our services or providers, but
20351        // this gives us a baseline and makes sure we don't get into an
20352        // infinite recursion.
20353        app.adjSeq = mAdjSeq;
20354        app.curRawAdj = adj;
20355        app.hasStartedServices = false;
20356
20357        if (mBackupTarget != null && app == mBackupTarget.app) {
20358            // If possible we want to avoid killing apps while they're being backed up
20359            if (adj > ProcessList.BACKUP_APP_ADJ) {
20360                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
20361                adj = ProcessList.BACKUP_APP_ADJ;
20362                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
20363                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
20364                }
20365                app.adjType = "backup";
20366                app.cached = false;
20367            }
20368            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
20369                procState = ActivityManager.PROCESS_STATE_BACKUP;
20370            }
20371        }
20372
20373        boolean mayBeTop = false;
20374
20375        for (int is = app.services.size()-1;
20376                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
20377                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
20378                        || procState > ActivityManager.PROCESS_STATE_TOP);
20379                is--) {
20380            ServiceRecord s = app.services.valueAt(is);
20381            if (s.startRequested) {
20382                app.hasStartedServices = true;
20383                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
20384                    procState = ActivityManager.PROCESS_STATE_SERVICE;
20385                }
20386                if (app.hasShownUi && app != mHomeProcess) {
20387                    // If this process has shown some UI, let it immediately
20388                    // go to the LRU list because it may be pretty heavy with
20389                    // UI stuff.  We'll tag it with a label just to help
20390                    // debug and understand what is going on.
20391                    if (adj > ProcessList.SERVICE_ADJ) {
20392                        app.adjType = "cch-started-ui-services";
20393                    }
20394                } else {
20395                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
20396                        // This service has seen some activity within
20397                        // recent memory, so we will keep its process ahead
20398                        // of the background processes.
20399                        if (adj > ProcessList.SERVICE_ADJ) {
20400                            adj = ProcessList.SERVICE_ADJ;
20401                            app.adjType = "started-services";
20402                            app.cached = false;
20403                        }
20404                    }
20405                    // If we have let the service slide into the background
20406                    // state, still have some text describing what it is doing
20407                    // even though the service no longer has an impact.
20408                    if (adj > ProcessList.SERVICE_ADJ) {
20409                        app.adjType = "cch-started-services";
20410                    }
20411                }
20412            }
20413
20414            for (int conni = s.connections.size()-1;
20415                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
20416                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
20417                            || procState > ActivityManager.PROCESS_STATE_TOP);
20418                    conni--) {
20419                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
20420                for (int i = 0;
20421                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
20422                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
20423                                || procState > ActivityManager.PROCESS_STATE_TOP);
20424                        i++) {
20425                    // XXX should compute this based on the max of
20426                    // all connected clients.
20427                    ConnectionRecord cr = clist.get(i);
20428                    if (cr.binding.client == app) {
20429                        // Binding to ourself is not interesting.
20430                        continue;
20431                    }
20432
20433                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
20434                        ProcessRecord client = cr.binding.client;
20435                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
20436                                TOP_APP, doingAll, now);
20437                        int clientProcState = client.curProcState;
20438                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
20439                            // If the other app is cached for any reason, for purposes here
20440                            // we are going to consider it empty.  The specific cached state
20441                            // doesn't propagate except under certain conditions.
20442                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20443                        }
20444                        String adjType = null;
20445                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
20446                            // Not doing bind OOM management, so treat
20447                            // this guy more like a started service.
20448                            if (app.hasShownUi && app != mHomeProcess) {
20449                                // If this process has shown some UI, let it immediately
20450                                // go to the LRU list because it may be pretty heavy with
20451                                // UI stuff.  We'll tag it with a label just to help
20452                                // debug and understand what is going on.
20453                                if (adj > clientAdj) {
20454                                    adjType = "cch-bound-ui-services";
20455                                }
20456                                app.cached = false;
20457                                clientAdj = adj;
20458                                clientProcState = procState;
20459                            } else {
20460                                if (now >= (s.lastActivity
20461                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
20462                                    // This service has not seen activity within
20463                                    // recent memory, so allow it to drop to the
20464                                    // LRU list if there is no other reason to keep
20465                                    // it around.  We'll also tag it with a label just
20466                                    // to help debug and undertand what is going on.
20467                                    if (adj > clientAdj) {
20468                                        adjType = "cch-bound-services";
20469                                    }
20470                                    clientAdj = adj;
20471                                }
20472                            }
20473                        }
20474                        if (adj > clientAdj) {
20475                            // If this process has recently shown UI, and
20476                            // the process that is binding to it is less
20477                            // important than being visible, then we don't
20478                            // care about the binding as much as we care
20479                            // about letting this process get into the LRU
20480                            // list to be killed and restarted if needed for
20481                            // memory.
20482                            if (app.hasShownUi && app != mHomeProcess
20483                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20484                                adjType = "cch-bound-ui-services";
20485                            } else {
20486                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
20487                                        |Context.BIND_IMPORTANT)) != 0) {
20488                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
20489                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
20490                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
20491                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
20492                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20493                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20494                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
20495                                    adj = clientAdj;
20496                                } else {
20497                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
20498                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
20499                                    }
20500                                }
20501                                if (!client.cached) {
20502                                    app.cached = false;
20503                                }
20504                                adjType = "service";
20505                            }
20506                        }
20507                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
20508                            // This will treat important bound services identically to
20509                            // the top app, which may behave differently than generic
20510                            // foreground work.
20511                            if (client.curSchedGroup > schedGroup) {
20512                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
20513                                    schedGroup = client.curSchedGroup;
20514                                } else {
20515                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20516                                }
20517                            }
20518                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
20519                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
20520                                    // Special handling of clients who are in the top state.
20521                                    // We *may* want to consider this process to be in the
20522                                    // top state as well, but only if there is not another
20523                                    // reason for it to be running.  Being on the top is a
20524                                    // special state, meaning you are specifically running
20525                                    // for the current top app.  If the process is already
20526                                    // running in the background for some other reason, it
20527                                    // is more important to continue considering it to be
20528                                    // in the background state.
20529                                    mayBeTop = true;
20530                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20531                                } else {
20532                                    // Special handling for above-top states (persistent
20533                                    // processes).  These should not bring the current process
20534                                    // into the top state, since they are not on top.  Instead
20535                                    // give them the best state after that.
20536                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
20537                                        clientProcState =
20538                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
20539                                    } else if (mWakefulness
20540                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
20541                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
20542                                                    != 0) {
20543                                        clientProcState =
20544                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
20545                                    } else {
20546                                        clientProcState =
20547                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20548                                    }
20549                                }
20550                            }
20551                        } else {
20552                            if (clientProcState <
20553                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
20554                                clientProcState =
20555                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
20556                            }
20557                        }
20558                        if (procState > clientProcState) {
20559                            procState = clientProcState;
20560                        }
20561                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20562                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
20563                            app.pendingUiClean = true;
20564                        }
20565                        if (adjType != null) {
20566                            app.adjType = adjType;
20567                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
20568                                    .REASON_SERVICE_IN_USE;
20569                            app.adjSource = cr.binding.client;
20570                            app.adjSourceProcState = clientProcState;
20571                            app.adjTarget = s.name;
20572                        }
20573                    }
20574                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
20575                        app.treatLikeActivity = true;
20576                    }
20577                    final ActivityRecord a = cr.activity;
20578                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
20579                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
20580                            (a.visible || a.state == ActivityState.RESUMED ||
20581                             a.state == ActivityState.PAUSING)) {
20582                            adj = ProcessList.FOREGROUND_APP_ADJ;
20583                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
20584                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
20585                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
20586                                } else {
20587                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20588                                }
20589                            }
20590                            app.cached = false;
20591                            app.adjType = "service";
20592                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
20593                                    .REASON_SERVICE_IN_USE;
20594                            app.adjSource = a;
20595                            app.adjSourceProcState = procState;
20596                            app.adjTarget = s.name;
20597                        }
20598                    }
20599                }
20600            }
20601        }
20602
20603        for (int provi = app.pubProviders.size()-1;
20604                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
20605                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
20606                        || procState > ActivityManager.PROCESS_STATE_TOP);
20607                provi--) {
20608            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
20609            for (int i = cpr.connections.size()-1;
20610                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
20611                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
20612                            || procState > ActivityManager.PROCESS_STATE_TOP);
20613                    i--) {
20614                ContentProviderConnection conn = cpr.connections.get(i);
20615                ProcessRecord client = conn.client;
20616                if (client == app) {
20617                    // Being our own client is not interesting.
20618                    continue;
20619                }
20620                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
20621                int clientProcState = client.curProcState;
20622                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
20623                    // If the other app is cached for any reason, for purposes here
20624                    // we are going to consider it empty.
20625                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20626                }
20627                if (adj > clientAdj) {
20628                    if (app.hasShownUi && app != mHomeProcess
20629                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20630                        app.adjType = "cch-ui-provider";
20631                    } else {
20632                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
20633                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
20634                        app.adjType = "provider";
20635                    }
20636                    app.cached &= client.cached;
20637                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
20638                            .REASON_PROVIDER_IN_USE;
20639                    app.adjSource = client;
20640                    app.adjSourceProcState = clientProcState;
20641                    app.adjTarget = cpr.name;
20642                }
20643                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
20644                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
20645                        // Special handling of clients who are in the top state.
20646                        // We *may* want to consider this process to be in the
20647                        // top state as well, but only if there is not another
20648                        // reason for it to be running.  Being on the top is a
20649                        // special state, meaning you are specifically running
20650                        // for the current top app.  If the process is already
20651                        // running in the background for some other reason, it
20652                        // is more important to continue considering it to be
20653                        // in the background state.
20654                        mayBeTop = true;
20655                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20656                    } else {
20657                        // Special handling for above-top states (persistent
20658                        // processes).  These should not bring the current process
20659                        // into the top state, since they are not on top.  Instead
20660                        // give them the best state after that.
20661                        clientProcState =
20662                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
20663                    }
20664                }
20665                if (procState > clientProcState) {
20666                    procState = clientProcState;
20667                }
20668                if (client.curSchedGroup > schedGroup) {
20669                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20670                }
20671            }
20672            // If the provider has external (non-framework) process
20673            // dependencies, ensure that its adjustment is at least
20674            // FOREGROUND_APP_ADJ.
20675            if (cpr.hasExternalProcessHandles()) {
20676                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
20677                    adj = ProcessList.FOREGROUND_APP_ADJ;
20678                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20679                    app.cached = false;
20680                    app.adjType = "provider";
20681                    app.adjTarget = cpr.name;
20682                }
20683                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20684                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20685                }
20686            }
20687        }
20688
20689        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
20690            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
20691                adj = ProcessList.PREVIOUS_APP_ADJ;
20692                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20693                app.cached = false;
20694                app.adjType = "provider";
20695            }
20696            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
20697                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
20698            }
20699        }
20700
20701        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
20702            // A client of one of our services or providers is in the top state.  We
20703            // *may* want to be in the top state, but not if we are already running in
20704            // the background for some other reason.  For the decision here, we are going
20705            // to pick out a few specific states that we want to remain in when a client
20706            // is top (states that tend to be longer-term) and otherwise allow it to go
20707            // to the top state.
20708            switch (procState) {
20709                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
20710                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
20711                case ActivityManager.PROCESS_STATE_SERVICE:
20712                    // These all are longer-term states, so pull them up to the top
20713                    // of the background states, but not all the way to the top state.
20714                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
20715                    break;
20716                default:
20717                    // Otherwise, top is a better choice, so take it.
20718                    procState = ActivityManager.PROCESS_STATE_TOP;
20719                    break;
20720            }
20721        }
20722
20723        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
20724            if (app.hasClientActivities) {
20725                // This is a cached process, but with client activities.  Mark it so.
20726                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
20727                app.adjType = "cch-client-act";
20728            } else if (app.treatLikeActivity) {
20729                // This is a cached process, but somebody wants us to treat it like it has
20730                // an activity, okay!
20731                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
20732                app.adjType = "cch-as-act";
20733            }
20734        }
20735
20736        if (adj == ProcessList.SERVICE_ADJ) {
20737            if (doingAll) {
20738                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
20739                mNewNumServiceProcs++;
20740                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
20741                if (!app.serviceb) {
20742                    // This service isn't far enough down on the LRU list to
20743                    // normally be a B service, but if we are low on RAM and it
20744                    // is large we want to force it down since we would prefer to
20745                    // keep launcher over it.
20746                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
20747                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
20748                        app.serviceHighRam = true;
20749                        app.serviceb = true;
20750                        //Slog.i(TAG, "ADJ " + app + " high ram!");
20751                    } else {
20752                        mNewNumAServiceProcs++;
20753                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
20754                    }
20755                } else {
20756                    app.serviceHighRam = false;
20757                }
20758            }
20759            if (app.serviceb) {
20760                adj = ProcessList.SERVICE_B_ADJ;
20761            }
20762        }
20763
20764        app.curRawAdj = adj;
20765
20766        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
20767        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
20768        if (adj > app.maxAdj) {
20769            adj = app.maxAdj;
20770            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
20771                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20772            }
20773        }
20774
20775        // Do final modification to adj.  Everything we do between here and applying
20776        // the final setAdj must be done in this function, because we will also use
20777        // it when computing the final cached adj later.  Note that we don't need to
20778        // worry about this for max adj above, since max adj will always be used to
20779        // keep it out of the cached vaues.
20780        app.curAdj = app.modifyRawOomAdj(adj);
20781        app.curSchedGroup = schedGroup;
20782        app.curProcState = procState;
20783        app.foregroundActivities = foregroundActivities;
20784
20785        return app.curRawAdj;
20786    }
20787
20788    /**
20789     * Record new PSS sample for a process.
20790     */
20791    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
20792            long now) {
20793        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
20794                swapPss * 1024);
20795        proc.lastPssTime = now;
20796        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
20797        if (DEBUG_PSS) Slog.d(TAG_PSS,
20798                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
20799                + " state=" + ProcessList.makeProcStateString(procState));
20800        if (proc.initialIdlePss == 0) {
20801            proc.initialIdlePss = pss;
20802        }
20803        proc.lastPss = pss;
20804        proc.lastSwapPss = swapPss;
20805        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
20806            proc.lastCachedPss = pss;
20807            proc.lastCachedSwapPss = swapPss;
20808        }
20809
20810        final SparseArray<Pair<Long, String>> watchUids
20811                = mMemWatchProcesses.getMap().get(proc.processName);
20812        Long check = null;
20813        if (watchUids != null) {
20814            Pair<Long, String> val = watchUids.get(proc.uid);
20815            if (val == null) {
20816                val = watchUids.get(0);
20817            }
20818            if (val != null) {
20819                check = val.first;
20820            }
20821        }
20822        if (check != null) {
20823            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
20824                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20825                if (!isDebuggable) {
20826                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
20827                        isDebuggable = true;
20828                    }
20829                }
20830                if (isDebuggable) {
20831                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
20832                    final ProcessRecord myProc = proc;
20833                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
20834                    mMemWatchDumpProcName = proc.processName;
20835                    mMemWatchDumpFile = heapdumpFile.toString();
20836                    mMemWatchDumpPid = proc.pid;
20837                    mMemWatchDumpUid = proc.uid;
20838                    BackgroundThread.getHandler().post(new Runnable() {
20839                        @Override
20840                        public void run() {
20841                            revokeUriPermission(ActivityThread.currentActivityThread()
20842                                            .getApplicationThread(),
20843                                    DumpHeapActivity.JAVA_URI,
20844                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
20845                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
20846                                    UserHandle.myUserId());
20847                            ParcelFileDescriptor fd = null;
20848                            try {
20849                                heapdumpFile.delete();
20850                                fd = ParcelFileDescriptor.open(heapdumpFile,
20851                                        ParcelFileDescriptor.MODE_CREATE |
20852                                                ParcelFileDescriptor.MODE_TRUNCATE |
20853                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
20854                                                ParcelFileDescriptor.MODE_APPEND);
20855                                IApplicationThread thread = myProc.thread;
20856                                if (thread != null) {
20857                                    try {
20858                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
20859                                                "Requesting dump heap from "
20860                                                + myProc + " to " + heapdumpFile);
20861                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
20862                                    } catch (RemoteException e) {
20863                                    }
20864                                }
20865                            } catch (FileNotFoundException e) {
20866                                e.printStackTrace();
20867                            } finally {
20868                                if (fd != null) {
20869                                    try {
20870                                        fd.close();
20871                                    } catch (IOException e) {
20872                                    }
20873                                }
20874                            }
20875                        }
20876                    });
20877                } else {
20878                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
20879                            + ", but debugging not enabled");
20880                }
20881            }
20882        }
20883    }
20884
20885    /**
20886     * Schedule PSS collection of a process.
20887     */
20888    void requestPssLocked(ProcessRecord proc, int procState) {
20889        if (mPendingPssProcesses.contains(proc)) {
20890            return;
20891        }
20892        if (mPendingPssProcesses.size() == 0) {
20893            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20894        }
20895        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
20896        proc.pssProcState = procState;
20897        mPendingPssProcesses.add(proc);
20898    }
20899
20900    /**
20901     * Schedule PSS collection of all processes.
20902     */
20903    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
20904        if (!always) {
20905            if (now < (mLastFullPssTime +
20906                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
20907                return;
20908            }
20909        }
20910        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
20911        mLastFullPssTime = now;
20912        mFullPssPending = true;
20913        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
20914        mPendingPssProcesses.clear();
20915        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20916            ProcessRecord app = mLruProcesses.get(i);
20917            if (app.thread == null
20918                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
20919                continue;
20920            }
20921            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
20922                app.pssProcState = app.setProcState;
20923                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20924                        mTestPssMode, isSleepingLocked(), now);
20925                mPendingPssProcesses.add(app);
20926            }
20927        }
20928        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20929    }
20930
20931    public void setTestPssMode(boolean enabled) {
20932        synchronized (this) {
20933            mTestPssMode = enabled;
20934            if (enabled) {
20935                // Whenever we enable the mode, we want to take a snapshot all of current
20936                // process mem use.
20937                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
20938            }
20939        }
20940    }
20941
20942    /**
20943     * Ask a given process to GC right now.
20944     */
20945    final void performAppGcLocked(ProcessRecord app) {
20946        try {
20947            app.lastRequestedGc = SystemClock.uptimeMillis();
20948            if (app.thread != null) {
20949                if (app.reportLowMemory) {
20950                    app.reportLowMemory = false;
20951                    app.thread.scheduleLowMemory();
20952                } else {
20953                    app.thread.processInBackground();
20954                }
20955            }
20956        } catch (Exception e) {
20957            // whatever.
20958        }
20959    }
20960
20961    /**
20962     * Returns true if things are idle enough to perform GCs.
20963     */
20964    private final boolean canGcNowLocked() {
20965        boolean processingBroadcasts = false;
20966        for (BroadcastQueue q : mBroadcastQueues) {
20967            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
20968                processingBroadcasts = true;
20969            }
20970        }
20971        return !processingBroadcasts
20972                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
20973    }
20974
20975    /**
20976     * Perform GCs on all processes that are waiting for it, but only
20977     * if things are idle.
20978     */
20979    final void performAppGcsLocked() {
20980        final int N = mProcessesToGc.size();
20981        if (N <= 0) {
20982            return;
20983        }
20984        if (canGcNowLocked()) {
20985            while (mProcessesToGc.size() > 0) {
20986                ProcessRecord proc = mProcessesToGc.remove(0);
20987                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
20988                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
20989                            <= SystemClock.uptimeMillis()) {
20990                        // To avoid spamming the system, we will GC processes one
20991                        // at a time, waiting a few seconds between each.
20992                        performAppGcLocked(proc);
20993                        scheduleAppGcsLocked();
20994                        return;
20995                    } else {
20996                        // It hasn't been long enough since we last GCed this
20997                        // process...  put it in the list to wait for its time.
20998                        addProcessToGcListLocked(proc);
20999                        break;
21000                    }
21001                }
21002            }
21003
21004            scheduleAppGcsLocked();
21005        }
21006    }
21007
21008    /**
21009     * If all looks good, perform GCs on all processes waiting for them.
21010     */
21011    final void performAppGcsIfAppropriateLocked() {
21012        if (canGcNowLocked()) {
21013            performAppGcsLocked();
21014            return;
21015        }
21016        // Still not idle, wait some more.
21017        scheduleAppGcsLocked();
21018    }
21019
21020    /**
21021     * Schedule the execution of all pending app GCs.
21022     */
21023    final void scheduleAppGcsLocked() {
21024        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
21025
21026        if (mProcessesToGc.size() > 0) {
21027            // Schedule a GC for the time to the next process.
21028            ProcessRecord proc = mProcessesToGc.get(0);
21029            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
21030
21031            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
21032            long now = SystemClock.uptimeMillis();
21033            if (when < (now+GC_TIMEOUT)) {
21034                when = now + GC_TIMEOUT;
21035            }
21036            mHandler.sendMessageAtTime(msg, when);
21037        }
21038    }
21039
21040    /**
21041     * Add a process to the array of processes waiting to be GCed.  Keeps the
21042     * list in sorted order by the last GC time.  The process can't already be
21043     * on the list.
21044     */
21045    final void addProcessToGcListLocked(ProcessRecord proc) {
21046        boolean added = false;
21047        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
21048            if (mProcessesToGc.get(i).lastRequestedGc <
21049                    proc.lastRequestedGc) {
21050                added = true;
21051                mProcessesToGc.add(i+1, proc);
21052                break;
21053            }
21054        }
21055        if (!added) {
21056            mProcessesToGc.add(0, proc);
21057        }
21058    }
21059
21060    /**
21061     * Set up to ask a process to GC itself.  This will either do it
21062     * immediately, or put it on the list of processes to gc the next
21063     * time things are idle.
21064     */
21065    final void scheduleAppGcLocked(ProcessRecord app) {
21066        long now = SystemClock.uptimeMillis();
21067        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
21068            return;
21069        }
21070        if (!mProcessesToGc.contains(app)) {
21071            addProcessToGcListLocked(app);
21072            scheduleAppGcsLocked();
21073        }
21074    }
21075
21076    final void checkExcessivePowerUsageLocked(boolean doKills) {
21077        updateCpuStatsNow();
21078
21079        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
21080        boolean doWakeKills = doKills;
21081        boolean doCpuKills = doKills;
21082        if (mLastPowerCheckRealtime == 0) {
21083            doWakeKills = false;
21084        }
21085        if (mLastPowerCheckUptime == 0) {
21086            doCpuKills = false;
21087        }
21088        if (stats.isScreenOn()) {
21089            doWakeKills = false;
21090        }
21091        final long curRealtime = SystemClock.elapsedRealtime();
21092        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
21093        final long curUptime = SystemClock.uptimeMillis();
21094        final long uptimeSince = curUptime - mLastPowerCheckUptime;
21095        mLastPowerCheckRealtime = curRealtime;
21096        mLastPowerCheckUptime = curUptime;
21097        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
21098            doWakeKills = false;
21099        }
21100        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
21101            doCpuKills = false;
21102        }
21103        int i = mLruProcesses.size();
21104        while (i > 0) {
21105            i--;
21106            ProcessRecord app = mLruProcesses.get(i);
21107            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
21108                long wtime;
21109                synchronized (stats) {
21110                    wtime = stats.getProcessWakeTime(app.info.uid,
21111                            app.pid, curRealtime);
21112                }
21113                long wtimeUsed = wtime - app.lastWakeTime;
21114                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
21115                if (DEBUG_POWER) {
21116                    StringBuilder sb = new StringBuilder(128);
21117                    sb.append("Wake for ");
21118                    app.toShortString(sb);
21119                    sb.append(": over ");
21120                    TimeUtils.formatDuration(realtimeSince, sb);
21121                    sb.append(" used ");
21122                    TimeUtils.formatDuration(wtimeUsed, sb);
21123                    sb.append(" (");
21124                    sb.append((wtimeUsed*100)/realtimeSince);
21125                    sb.append("%)");
21126                    Slog.i(TAG_POWER, sb.toString());
21127                    sb.setLength(0);
21128                    sb.append("CPU for ");
21129                    app.toShortString(sb);
21130                    sb.append(": over ");
21131                    TimeUtils.formatDuration(uptimeSince, sb);
21132                    sb.append(" used ");
21133                    TimeUtils.formatDuration(cputimeUsed, sb);
21134                    sb.append(" (");
21135                    sb.append((cputimeUsed*100)/uptimeSince);
21136                    sb.append("%)");
21137                    Slog.i(TAG_POWER, sb.toString());
21138                }
21139                // If a process has held a wake lock for more
21140                // than 50% of the time during this period,
21141                // that sounds bad.  Kill!
21142                if (doWakeKills && realtimeSince > 0
21143                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
21144                    synchronized (stats) {
21145                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
21146                                realtimeSince, wtimeUsed);
21147                    }
21148                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
21149                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
21150                } else if (doCpuKills && uptimeSince > 0
21151                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
21152                    synchronized (stats) {
21153                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
21154                                uptimeSince, cputimeUsed);
21155                    }
21156                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
21157                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
21158                } else {
21159                    app.lastWakeTime = wtime;
21160                    app.lastCpuTime = app.curCpuTime;
21161                }
21162            }
21163        }
21164    }
21165
21166    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
21167            long nowElapsed) {
21168        boolean success = true;
21169
21170        if (app.curRawAdj != app.setRawAdj) {
21171            app.setRawAdj = app.curRawAdj;
21172        }
21173
21174        int changes = 0;
21175
21176        if (app.curAdj != app.setAdj) {
21177            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
21178            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21179                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
21180                    + app.adjType);
21181            app.setAdj = app.curAdj;
21182            app.verifiedAdj = ProcessList.INVALID_ADJ;
21183        }
21184
21185        if (app.setSchedGroup != app.curSchedGroup) {
21186            int oldSchedGroup = app.setSchedGroup;
21187            app.setSchedGroup = app.curSchedGroup;
21188            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21189                    "Setting sched group of " + app.processName
21190                    + " to " + app.curSchedGroup);
21191            if (app.waitingToKill != null && app.curReceivers.isEmpty()
21192                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
21193                app.kill(app.waitingToKill, true);
21194                success = false;
21195            } else {
21196                int processGroup;
21197                switch (app.curSchedGroup) {
21198                    case ProcessList.SCHED_GROUP_BACKGROUND:
21199                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
21200                        break;
21201                    case ProcessList.SCHED_GROUP_TOP_APP:
21202                    case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
21203                        processGroup = Process.THREAD_GROUP_TOP_APP;
21204                        break;
21205                    default:
21206                        processGroup = Process.THREAD_GROUP_DEFAULT;
21207                        break;
21208                }
21209                long oldId = Binder.clearCallingIdentity();
21210                try {
21211                    Process.setProcessGroup(app.pid, processGroup);
21212                    if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
21213                        // do nothing if we already switched to RT
21214                        if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
21215                            // Switch VR thread for app to SCHED_FIFO
21216                            if (mInVrMode && app.vrThreadTid != 0) {
21217                                try {
21218                                    Process.setThreadScheduler(app.vrThreadTid,
21219                                        Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
21220                                } catch (IllegalArgumentException e) {
21221                                    // thread died, ignore
21222                                }
21223                            }
21224                            if (mUseFifoUiScheduling) {
21225                                // Switch UI pipeline for app to SCHED_FIFO
21226                                app.savedPriority = Process.getThreadPriority(app.pid);
21227                                try {
21228                                    Process.setThreadScheduler(app.pid,
21229                                        Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
21230                                } catch (IllegalArgumentException e) {
21231                                    // thread died, ignore
21232                                }
21233                                if (app.renderThreadTid != 0) {
21234                                    try {
21235                                        Process.setThreadScheduler(app.renderThreadTid,
21236                                            Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
21237                                    } catch (IllegalArgumentException e) {
21238                                        // thread died, ignore
21239                                    }
21240                                    if (DEBUG_OOM_ADJ) {
21241                                        Slog.d("UI_FIFO", "Set RenderThread (TID " +
21242                                            app.renderThreadTid + ") to FIFO");
21243                                    }
21244                                } else {
21245                                    if (DEBUG_OOM_ADJ) {
21246                                        Slog.d("UI_FIFO", "Not setting RenderThread TID");
21247                                    }
21248                                }
21249                            } else {
21250                                // Boost priority for top app UI and render threads
21251                                Process.setThreadPriority(app.pid, -10);
21252                                if (app.renderThreadTid != 0) {
21253                                    try {
21254                                        Process.setThreadPriority(app.renderThreadTid, -10);
21255                                    } catch (IllegalArgumentException e) {
21256                                        // thread died, ignore
21257                                    }
21258                                }
21259                            }
21260                        }
21261                    } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
21262                               app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
21263                        // Reset VR thread to SCHED_OTHER
21264                        // Safe to do even if we're not in VR mode
21265                        if (app.vrThreadTid != 0) {
21266                            Process.setThreadScheduler(app.vrThreadTid, Process.SCHED_OTHER, 0);
21267                        }
21268                        if (mUseFifoUiScheduling) {
21269                            // Reset UI pipeline to SCHED_OTHER
21270                            Process.setThreadScheduler(app.pid, Process.SCHED_OTHER, 0);
21271                            Process.setThreadPriority(app.pid, app.savedPriority);
21272                            if (app.renderThreadTid != 0) {
21273                                Process.setThreadScheduler(app.renderThreadTid,
21274                                    Process.SCHED_OTHER, 0);
21275                                Process.setThreadPriority(app.renderThreadTid, -4);
21276                            }
21277                        } else {
21278                            // Reset priority for top app UI and render threads
21279                            Process.setThreadPriority(app.pid, 0);
21280                            if (app.renderThreadTid != 0) {
21281                                Process.setThreadPriority(app.renderThreadTid, 0);
21282                            }
21283                        }
21284                    }
21285                } catch (Exception e) {
21286                    Slog.w(TAG, "Failed setting process group of " + app.pid
21287                            + " to " + app.curSchedGroup);
21288                    e.printStackTrace();
21289                } finally {
21290                    Binder.restoreCallingIdentity(oldId);
21291                }
21292            }
21293        }
21294        if (app.repForegroundActivities != app.foregroundActivities) {
21295            app.repForegroundActivities = app.foregroundActivities;
21296            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
21297        }
21298        if (app.repProcState != app.curProcState) {
21299            app.repProcState = app.curProcState;
21300            if (app.thread != null) {
21301                try {
21302                    if (false) {
21303                        //RuntimeException h = new RuntimeException("here");
21304                        Slog.i(TAG, "Sending new process state " + app.repProcState
21305                                + " to " + app /*, h*/);
21306                    }
21307                    app.thread.setProcessState(app.repProcState);
21308                } catch (RemoteException e) {
21309                }
21310            }
21311        }
21312        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
21313                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
21314            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
21315                // Experimental code to more aggressively collect pss while
21316                // running test...  the problem is that this tends to collect
21317                // the data right when a process is transitioning between process
21318                // states, which well tend to give noisy data.
21319                long start = SystemClock.uptimeMillis();
21320                long pss = Debug.getPss(app.pid, mTmpLong, null);
21321                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
21322                mPendingPssProcesses.remove(app);
21323                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
21324                        + " to " + app.curProcState + ": "
21325                        + (SystemClock.uptimeMillis()-start) + "ms");
21326            }
21327            app.lastStateTime = now;
21328            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
21329                    mTestPssMode, isSleepingLocked(), now);
21330            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
21331                    + ProcessList.makeProcStateString(app.setProcState) + " to "
21332                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
21333                    + (app.nextPssTime-now) + ": " + app);
21334        } else {
21335            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
21336                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
21337                    mTestPssMode)))) {
21338                requestPssLocked(app, app.setProcState);
21339                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
21340                        mTestPssMode, isSleepingLocked(), now);
21341            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
21342                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
21343        }
21344        if (app.setProcState != app.curProcState) {
21345            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21346                    "Proc state change of " + app.processName
21347                            + " to " + app.curProcState);
21348            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
21349            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
21350            if (setImportant && !curImportant) {
21351                // This app is no longer something we consider important enough to allow to
21352                // use arbitrary amounts of battery power.  Note
21353                // its current wake lock time to later know to kill it if
21354                // it is not behaving well.
21355                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
21356                synchronized (stats) {
21357                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
21358                            app.pid, nowElapsed);
21359                }
21360                app.lastCpuTime = app.curCpuTime;
21361
21362            }
21363            // Inform UsageStats of important process state change
21364            // Must be called before updating setProcState
21365            maybeUpdateUsageStatsLocked(app, nowElapsed);
21366
21367            app.setProcState = app.curProcState;
21368            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
21369                app.notCachedSinceIdle = false;
21370            }
21371            if (!doingAll) {
21372                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
21373            } else {
21374                app.procStateChanged = true;
21375            }
21376        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
21377                > USAGE_STATS_INTERACTION_INTERVAL) {
21378            // For apps that sit around for a long time in the interactive state, we need
21379            // to report this at least once a day so they don't go idle.
21380            maybeUpdateUsageStatsLocked(app, nowElapsed);
21381        }
21382
21383        if (changes != 0) {
21384            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21385                    "Changes in " + app + ": " + changes);
21386            int i = mPendingProcessChanges.size()-1;
21387            ProcessChangeItem item = null;
21388            while (i >= 0) {
21389                item = mPendingProcessChanges.get(i);
21390                if (item.pid == app.pid) {
21391                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21392                            "Re-using existing item: " + item);
21393                    break;
21394                }
21395                i--;
21396            }
21397            if (i < 0) {
21398                // No existing item in pending changes; need a new one.
21399                final int NA = mAvailProcessChanges.size();
21400                if (NA > 0) {
21401                    item = mAvailProcessChanges.remove(NA-1);
21402                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21403                            "Retrieving available item: " + item);
21404                } else {
21405                    item = new ProcessChangeItem();
21406                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21407                            "Allocating new item: " + item);
21408                }
21409                item.changes = 0;
21410                item.pid = app.pid;
21411                item.uid = app.info.uid;
21412                if (mPendingProcessChanges.size() == 0) {
21413                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21414                            "*** Enqueueing dispatch processes changed!");
21415                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
21416                }
21417                mPendingProcessChanges.add(item);
21418            }
21419            item.changes |= changes;
21420            item.foregroundActivities = app.repForegroundActivities;
21421            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21422                    "Item " + Integer.toHexString(System.identityHashCode(item))
21423                    + " " + app.toShortString() + ": changes=" + item.changes
21424                    + " foreground=" + item.foregroundActivities
21425                    + " type=" + app.adjType + " source=" + app.adjSource
21426                    + " target=" + app.adjTarget);
21427        }
21428
21429        return success;
21430    }
21431
21432    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
21433        final UidRecord.ChangeItem pendingChange;
21434        if (uidRec == null || uidRec.pendingChange == null) {
21435            if (mPendingUidChanges.size() == 0) {
21436                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21437                        "*** Enqueueing dispatch uid changed!");
21438                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
21439            }
21440            final int NA = mAvailUidChanges.size();
21441            if (NA > 0) {
21442                pendingChange = mAvailUidChanges.remove(NA-1);
21443                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21444                        "Retrieving available item: " + pendingChange);
21445            } else {
21446                pendingChange = new UidRecord.ChangeItem();
21447                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21448                        "Allocating new item: " + pendingChange);
21449            }
21450            if (uidRec != null) {
21451                uidRec.pendingChange = pendingChange;
21452                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
21453                    // If this uid is going away, and we haven't yet reported it is gone,
21454                    // then do so now.
21455                    change = UidRecord.CHANGE_GONE_IDLE;
21456                }
21457            } else if (uid < 0) {
21458                throw new IllegalArgumentException("No UidRecord or uid");
21459            }
21460            pendingChange.uidRecord = uidRec;
21461            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
21462            mPendingUidChanges.add(pendingChange);
21463        } else {
21464            pendingChange = uidRec.pendingChange;
21465            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
21466                change = UidRecord.CHANGE_GONE_IDLE;
21467            }
21468        }
21469        pendingChange.change = change;
21470        pendingChange.processState = uidRec != null
21471                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
21472        pendingChange.ephemeral = uidRec.ephemeral;
21473
21474        // Directly update the power manager, since we sit on top of it and it is critical
21475        // it be kept in sync (so wake locks will be held as soon as appropriate).
21476        if (mLocalPowerManager != null) {
21477            switch (change) {
21478                case UidRecord.CHANGE_GONE:
21479                case UidRecord.CHANGE_GONE_IDLE:
21480                    mLocalPowerManager.uidGone(pendingChange.uid);
21481                    break;
21482                case UidRecord.CHANGE_IDLE:
21483                    mLocalPowerManager.uidIdle(pendingChange.uid);
21484                    break;
21485                case UidRecord.CHANGE_ACTIVE:
21486                    mLocalPowerManager.uidActive(pendingChange.uid);
21487                    break;
21488                default:
21489                    mLocalPowerManager.updateUidProcState(pendingChange.uid,
21490                            pendingChange.processState);
21491                    break;
21492            }
21493        }
21494    }
21495
21496    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
21497            String authority) {
21498        if (app == null) return;
21499        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
21500            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
21501            if (userState == null) return;
21502            final long now = SystemClock.elapsedRealtime();
21503            Long lastReported = userState.mProviderLastReportedFg.get(authority);
21504            if (lastReported == null || lastReported < now - 60 * 1000L) {
21505                if (mSystemReady) {
21506                    // Cannot touch the user stats if not system ready
21507                    mUsageStatsService.reportContentProviderUsage(
21508                            authority, providerPkgName, app.userId);
21509                }
21510                userState.mProviderLastReportedFg.put(authority, now);
21511            }
21512        }
21513    }
21514
21515    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
21516        if (DEBUG_USAGE_STATS) {
21517            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
21518                    + "] state changes: old = " + app.setProcState + ", new = "
21519                    + app.curProcState);
21520        }
21521        if (mUsageStatsService == null) {
21522            return;
21523        }
21524        boolean isInteraction;
21525        // To avoid some abuse patterns, we are going to be careful about what we consider
21526        // to be an app interaction.  Being the top activity doesn't count while the display
21527        // is sleeping, nor do short foreground services.
21528        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
21529            isInteraction = true;
21530            app.fgInteractionTime = 0;
21531        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
21532            if (app.fgInteractionTime == 0) {
21533                app.fgInteractionTime = nowElapsed;
21534                isInteraction = false;
21535            } else {
21536                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
21537            }
21538        } else {
21539            // If the app was being forced to the foreground, by say a Toast, then
21540            // no need to treat it as an interaction
21541            isInteraction = app.forcingToForeground == null
21542                    && app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21543            app.fgInteractionTime = 0;
21544        }
21545        if (isInteraction && (!app.reportedInteraction
21546                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
21547            app.interactionEventTime = nowElapsed;
21548            String[] packages = app.getPackageList();
21549            if (packages != null) {
21550                for (int i = 0; i < packages.length; i++) {
21551                    mUsageStatsService.reportEvent(packages[i], app.userId,
21552                            UsageEvents.Event.SYSTEM_INTERACTION);
21553                }
21554            }
21555        }
21556        app.reportedInteraction = isInteraction;
21557        if (!isInteraction) {
21558            app.interactionEventTime = 0;
21559        }
21560    }
21561
21562    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
21563        if (proc.thread != null) {
21564            if (proc.baseProcessTracker != null) {
21565                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
21566            }
21567        }
21568    }
21569
21570    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
21571            ProcessRecord TOP_APP, boolean doingAll, long now) {
21572        if (app.thread == null) {
21573            return false;
21574        }
21575
21576        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
21577
21578        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
21579    }
21580
21581    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
21582            boolean oomAdj) {
21583        if (isForeground != proc.foregroundServices) {
21584            proc.foregroundServices = isForeground;
21585            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
21586                    proc.info.uid);
21587            if (isForeground) {
21588                if (curProcs == null) {
21589                    curProcs = new ArrayList<ProcessRecord>();
21590                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
21591                }
21592                if (!curProcs.contains(proc)) {
21593                    curProcs.add(proc);
21594                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
21595                            proc.info.packageName, proc.info.uid);
21596                }
21597            } else {
21598                if (curProcs != null) {
21599                    if (curProcs.remove(proc)) {
21600                        mBatteryStatsService.noteEvent(
21601                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
21602                                proc.info.packageName, proc.info.uid);
21603                        if (curProcs.size() <= 0) {
21604                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
21605                        }
21606                    }
21607                }
21608            }
21609            if (oomAdj) {
21610                updateOomAdjLocked();
21611            }
21612        }
21613    }
21614
21615    private final ActivityRecord resumedAppLocked() {
21616        ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
21617        String pkg;
21618        int uid;
21619        if (act != null) {
21620            pkg = act.packageName;
21621            uid = act.info.applicationInfo.uid;
21622        } else {
21623            pkg = null;
21624            uid = -1;
21625        }
21626        // Has the UID or resumed package name changed?
21627        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
21628                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
21629            if (mCurResumedPackage != null) {
21630                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
21631                        mCurResumedPackage, mCurResumedUid);
21632            }
21633            mCurResumedPackage = pkg;
21634            mCurResumedUid = uid;
21635            if (mCurResumedPackage != null) {
21636                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
21637                        mCurResumedPackage, mCurResumedUid);
21638            }
21639        }
21640        return act;
21641    }
21642
21643    final boolean updateOomAdjLocked(ProcessRecord app) {
21644        final ActivityRecord TOP_ACT = resumedAppLocked();
21645        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
21646        final boolean wasCached = app.cached;
21647
21648        mAdjSeq++;
21649
21650        // This is the desired cached adjusment we want to tell it to use.
21651        // If our app is currently cached, we know it, and that is it.  Otherwise,
21652        // we don't know it yet, and it needs to now be cached we will then
21653        // need to do a complete oom adj.
21654        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
21655                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
21656        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
21657                SystemClock.uptimeMillis());
21658        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
21659            // Changed to/from cached state, so apps after it in the LRU
21660            // list may also be changed.
21661            updateOomAdjLocked();
21662        }
21663        return success;
21664    }
21665
21666    final void updateOomAdjLocked() {
21667        final ActivityRecord TOP_ACT = resumedAppLocked();
21668        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
21669        final long now = SystemClock.uptimeMillis();
21670        final long nowElapsed = SystemClock.elapsedRealtime();
21671        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
21672        final int N = mLruProcesses.size();
21673
21674        if (false) {
21675            RuntimeException e = new RuntimeException();
21676            e.fillInStackTrace();
21677            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
21678        }
21679
21680        // Reset state in all uid records.
21681        for (int i=mActiveUids.size()-1; i>=0; i--) {
21682            final UidRecord uidRec = mActiveUids.valueAt(i);
21683            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21684                    "Starting update of " + uidRec);
21685            uidRec.reset();
21686        }
21687
21688        mStackSupervisor.rankTaskLayersIfNeeded();
21689
21690        mAdjSeq++;
21691        mNewNumServiceProcs = 0;
21692        mNewNumAServiceProcs = 0;
21693
21694        final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
21695        final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit;
21696
21697        // Let's determine how many processes we have running vs.
21698        // how many slots we have for background processes; we may want
21699        // to put multiple processes in a slot of there are enough of
21700        // them.
21701        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
21702                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
21703        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
21704        if (numEmptyProcs > cachedProcessLimit) {
21705            // If there are more empty processes than our limit on cached
21706            // processes, then use the cached process limit for the factor.
21707            // This ensures that the really old empty processes get pushed
21708            // down to the bottom, so if we are running low on memory we will
21709            // have a better chance at keeping around more cached processes
21710            // instead of a gazillion empty processes.
21711            numEmptyProcs = cachedProcessLimit;
21712        }
21713        int emptyFactor = numEmptyProcs/numSlots;
21714        if (emptyFactor < 1) emptyFactor = 1;
21715        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
21716        if (cachedFactor < 1) cachedFactor = 1;
21717        int stepCached = 0;
21718        int stepEmpty = 0;
21719        int numCached = 0;
21720        int numEmpty = 0;
21721        int numTrimming = 0;
21722
21723        mNumNonCachedProcs = 0;
21724        mNumCachedHiddenProcs = 0;
21725
21726        // First update the OOM adjustment for each of the
21727        // application processes based on their current state.
21728        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
21729        int nextCachedAdj = curCachedAdj+1;
21730        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
21731        int nextEmptyAdj = curEmptyAdj+2;
21732        for (int i=N-1; i>=0; i--) {
21733            ProcessRecord app = mLruProcesses.get(i);
21734            if (!app.killedByAm && app.thread != null) {
21735                app.procStateChanged = false;
21736                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
21737
21738                // If we haven't yet assigned the final cached adj
21739                // to the process, do that now.
21740                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
21741                    switch (app.curProcState) {
21742                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
21743                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
21744                            // This process is a cached process holding activities...
21745                            // assign it the next cached value for that type, and then
21746                            // step that cached level.
21747                            app.curRawAdj = curCachedAdj;
21748                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
21749                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
21750                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
21751                                    + ")");
21752                            if (curCachedAdj != nextCachedAdj) {
21753                                stepCached++;
21754                                if (stepCached >= cachedFactor) {
21755                                    stepCached = 0;
21756                                    curCachedAdj = nextCachedAdj;
21757                                    nextCachedAdj += 2;
21758                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
21759                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
21760                                    }
21761                                }
21762                            }
21763                            break;
21764                        default:
21765                            // For everything else, assign next empty cached process
21766                            // level and bump that up.  Note that this means that
21767                            // long-running services that have dropped down to the
21768                            // cached level will be treated as empty (since their process
21769                            // state is still as a service), which is what we want.
21770                            app.curRawAdj = curEmptyAdj;
21771                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
21772                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
21773                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
21774                                    + ")");
21775                            if (curEmptyAdj != nextEmptyAdj) {
21776                                stepEmpty++;
21777                                if (stepEmpty >= emptyFactor) {
21778                                    stepEmpty = 0;
21779                                    curEmptyAdj = nextEmptyAdj;
21780                                    nextEmptyAdj += 2;
21781                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
21782                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
21783                                    }
21784                                }
21785                            }
21786                            break;
21787                    }
21788                }
21789
21790                applyOomAdjLocked(app, true, now, nowElapsed);
21791
21792                // Count the number of process types.
21793                switch (app.curProcState) {
21794                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
21795                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
21796                        mNumCachedHiddenProcs++;
21797                        numCached++;
21798                        if (numCached > cachedProcessLimit) {
21799                            app.kill("cached #" + numCached, true);
21800                        }
21801                        break;
21802                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
21803                        if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
21804                                && app.lastActivityTime < oldTime) {
21805                            app.kill("empty for "
21806                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
21807                                    / 1000) + "s", true);
21808                        } else {
21809                            numEmpty++;
21810                            if (numEmpty > emptyProcessLimit) {
21811                                app.kill("empty #" + numEmpty, true);
21812                            }
21813                        }
21814                        break;
21815                    default:
21816                        mNumNonCachedProcs++;
21817                        break;
21818                }
21819
21820                if (app.isolated && app.services.size() <= 0) {
21821                    // If this is an isolated process, and there are no
21822                    // services running in it, then the process is no longer
21823                    // needed.  We agressively kill these because we can by
21824                    // definition not re-use the same process again, and it is
21825                    // good to avoid having whatever code was running in them
21826                    // left sitting around after no longer needed.
21827                    app.kill("isolated not needed", true);
21828                } else {
21829                    // Keeping this process, update its uid.
21830                    final UidRecord uidRec = app.uidRecord;
21831                    if (uidRec != null) {
21832                        uidRec.ephemeral = app.info.isInstantApp();
21833                        if (uidRec.curProcState > app.curProcState) {
21834                            uidRec.curProcState = app.curProcState;
21835                        }
21836                    }
21837                }
21838
21839                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21840                        && !app.killedByAm) {
21841                    numTrimming++;
21842                }
21843            }
21844        }
21845
21846        for (int i = mActiveUids.size() - 1; i >= 0; --i) {
21847            incrementProcStateSeqIfNeeded(mActiveUids.valueAt(i));
21848        }
21849
21850        mNumServiceProcs = mNewNumServiceProcs;
21851
21852        // Now determine the memory trimming level of background processes.
21853        // Unfortunately we need to start at the back of the list to do this
21854        // properly.  We only do this if the number of background apps we
21855        // are managing to keep around is less than half the maximum we desire;
21856        // if we are keeping a good number around, we'll let them use whatever
21857        // memory they want.
21858        final int numCachedAndEmpty = numCached + numEmpty;
21859        int memFactor;
21860        if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
21861                && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
21862            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
21863                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
21864            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
21865                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
21866            } else {
21867                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
21868            }
21869        } else {
21870            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
21871        }
21872        // We always allow the memory level to go up (better).  We only allow it to go
21873        // down if we are in a state where that is allowed, *and* the total number of processes
21874        // has gone down since last time.
21875        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
21876                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
21877                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
21878        if (memFactor > mLastMemoryLevel) {
21879            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
21880                memFactor = mLastMemoryLevel;
21881                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
21882            }
21883        }
21884        if (memFactor != mLastMemoryLevel) {
21885            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
21886        }
21887        mLastMemoryLevel = memFactor;
21888        mLastNumProcesses = mLruProcesses.size();
21889        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
21890        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
21891        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
21892            if (mLowRamStartTime == 0) {
21893                mLowRamStartTime = now;
21894            }
21895            int step = 0;
21896            int fgTrimLevel;
21897            switch (memFactor) {
21898                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
21899                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
21900                    break;
21901                case ProcessStats.ADJ_MEM_FACTOR_LOW:
21902                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
21903                    break;
21904                default:
21905                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
21906                    break;
21907            }
21908            int factor = numTrimming/3;
21909            int minFactor = 2;
21910            if (mHomeProcess != null) minFactor++;
21911            if (mPreviousProcess != null) minFactor++;
21912            if (factor < minFactor) factor = minFactor;
21913            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
21914            for (int i=N-1; i>=0; i--) {
21915                ProcessRecord app = mLruProcesses.get(i);
21916                if (allChanged || app.procStateChanged) {
21917                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
21918                    app.procStateChanged = false;
21919                }
21920                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21921                        && !app.killedByAm) {
21922                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
21923                        try {
21924                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21925                                    "Trimming memory of " + app.processName + " to " + curLevel);
21926                            app.thread.scheduleTrimMemory(curLevel);
21927                        } catch (RemoteException e) {
21928                        }
21929                        if (false) {
21930                            // For now we won't do this; our memory trimming seems
21931                            // to be good enough at this point that destroying
21932                            // activities causes more harm than good.
21933                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
21934                                    && app != mHomeProcess && app != mPreviousProcess) {
21935                                // Need to do this on its own message because the stack may not
21936                                // be in a consistent state at this point.
21937                                // For these apps we will also finish their activities
21938                                // to help them free memory.
21939                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
21940                            }
21941                        }
21942                    }
21943                    app.trimMemoryLevel = curLevel;
21944                    step++;
21945                    if (step >= factor) {
21946                        step = 0;
21947                        switch (curLevel) {
21948                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
21949                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
21950                                break;
21951                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
21952                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21953                                break;
21954                        }
21955                    }
21956                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21957                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
21958                            && app.thread != null) {
21959                        try {
21960                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21961                                    "Trimming memory of heavy-weight " + app.processName
21962                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21963                            app.thread.scheduleTrimMemory(
21964                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21965                        } catch (RemoteException e) {
21966                        }
21967                    }
21968                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21969                } else {
21970                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21971                            || app.systemNoUi) && app.pendingUiClean) {
21972                        // If this application is now in the background and it
21973                        // had done UI, then give it the special trim level to
21974                        // have it free UI resources.
21975                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
21976                        if (app.trimMemoryLevel < level && app.thread != null) {
21977                            try {
21978                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21979                                        "Trimming memory of bg-ui " + app.processName
21980                                        + " to " + level);
21981                                app.thread.scheduleTrimMemory(level);
21982                            } catch (RemoteException e) {
21983                            }
21984                        }
21985                        app.pendingUiClean = false;
21986                    }
21987                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
21988                        try {
21989                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21990                                    "Trimming memory of fg " + app.processName
21991                                    + " to " + fgTrimLevel);
21992                            app.thread.scheduleTrimMemory(fgTrimLevel);
21993                        } catch (RemoteException e) {
21994                        }
21995                    }
21996                    app.trimMemoryLevel = fgTrimLevel;
21997                }
21998            }
21999        } else {
22000            if (mLowRamStartTime != 0) {
22001                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
22002                mLowRamStartTime = 0;
22003            }
22004            for (int i=N-1; i>=0; i--) {
22005                ProcessRecord app = mLruProcesses.get(i);
22006                if (allChanged || app.procStateChanged) {
22007                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
22008                    app.procStateChanged = false;
22009                }
22010                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22011                        || app.systemNoUi) && app.pendingUiClean) {
22012                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
22013                            && app.thread != null) {
22014                        try {
22015                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22016                                    "Trimming memory of ui hidden " + app.processName
22017                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22018                            app.thread.scheduleTrimMemory(
22019                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22020                        } catch (RemoteException e) {
22021                        }
22022                    }
22023                    app.pendingUiClean = false;
22024                }
22025                app.trimMemoryLevel = 0;
22026            }
22027        }
22028
22029        if (mAlwaysFinishActivities) {
22030            // Need to do this on its own message because the stack may not
22031            // be in a consistent state at this point.
22032            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
22033        }
22034
22035        if (allChanged) {
22036            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
22037        }
22038
22039        // Update from any uid changes.
22040        if (mLocalPowerManager != null) {
22041            mLocalPowerManager.startUidChanges();
22042        }
22043        for (int i=mActiveUids.size()-1; i>=0; i--) {
22044            final UidRecord uidRec = mActiveUids.valueAt(i);
22045            int uidChange = UidRecord.CHANGE_PROCSTATE;
22046            if (uidRec.setProcState != uidRec.curProcState
22047                    || uidRec.setWhitelist != uidRec.curWhitelist) {
22048                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22049                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
22050                        + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist
22051                        + " to " + uidRec.curWhitelist);
22052                if (ActivityManager.isProcStateBackground(uidRec.curProcState)
22053                        && !uidRec.curWhitelist) {
22054                    // UID is now in the background (and not on the temp whitelist).  Was it
22055                    // previously in the foreground (or on the temp whitelist)?
22056                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)
22057                            || uidRec.setWhitelist) {
22058                        uidRec.lastBackgroundTime = nowElapsed;
22059                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
22060                            // Note: the background settle time is in elapsed realtime, while
22061                            // the handler time base is uptime.  All this means is that we may
22062                            // stop background uids later than we had intended, but that only
22063                            // happens because the device was sleeping so we are okay anyway.
22064                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
22065                        }
22066                    }
22067                } else {
22068                    if (uidRec.idle) {
22069                        uidChange = UidRecord.CHANGE_ACTIVE;
22070                        uidRec.idle = false;
22071                    }
22072                    uidRec.lastBackgroundTime = 0;
22073                }
22074                uidRec.setProcState = uidRec.curProcState;
22075                uidRec.setWhitelist = uidRec.curWhitelist;
22076                enqueueUidChangeLocked(uidRec, -1, uidChange);
22077                noteUidProcessState(uidRec.uid, uidRec.curProcState);
22078            }
22079        }
22080        if (mLocalPowerManager != null) {
22081            mLocalPowerManager.finishUidChanges();
22082        }
22083
22084        if (mProcessStats.shouldWriteNowLocked(now)) {
22085            mHandler.post(new Runnable() {
22086                @Override public void run() {
22087                    synchronized (ActivityManagerService.this) {
22088                        mProcessStats.writeStateAsyncLocked();
22089                    }
22090                }
22091            });
22092        }
22093
22094        if (DEBUG_OOM_ADJ) {
22095            final long duration = SystemClock.uptimeMillis() - now;
22096            if (false) {
22097                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
22098                        new RuntimeException("here").fillInStackTrace());
22099            } else {
22100                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
22101            }
22102        }
22103    }
22104
22105    @Override
22106    public void makePackageIdle(String packageName, int userId) {
22107        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
22108                != PackageManager.PERMISSION_GRANTED) {
22109            String msg = "Permission Denial: makePackageIdle() from pid="
22110                    + Binder.getCallingPid()
22111                    + ", uid=" + Binder.getCallingUid()
22112                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
22113            Slog.w(TAG, msg);
22114            throw new SecurityException(msg);
22115        }
22116        final int callingPid = Binder.getCallingPid();
22117        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
22118                userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
22119        long callingId = Binder.clearCallingIdentity();
22120        synchronized(this) {
22121            try {
22122                IPackageManager pm = AppGlobals.getPackageManager();
22123                int pkgUid = -1;
22124                try {
22125                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
22126                            | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
22127                } catch (RemoteException e) {
22128                }
22129                if (pkgUid == -1) {
22130                    throw new IllegalArgumentException("Unknown package name " + packageName);
22131                }
22132
22133                if (mLocalPowerManager != null) {
22134                    mLocalPowerManager.startUidChanges();
22135                }
22136                final int appId = UserHandle.getAppId(pkgUid);
22137                final int N = mActiveUids.size();
22138                for (int i=N-1; i>=0; i--) {
22139                    final UidRecord uidRec = mActiveUids.valueAt(i);
22140                    final long bgTime = uidRec.lastBackgroundTime;
22141                    if (bgTime > 0 && !uidRec.idle) {
22142                        if (UserHandle.getAppId(uidRec.uid) == appId) {
22143                            if (userId == UserHandle.USER_ALL ||
22144                                    userId == UserHandle.getUserId(uidRec.uid)) {
22145                                uidRec.idle = true;
22146                                Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
22147                                        + " from package " + packageName + " user " + userId);
22148                                doStopUidLocked(uidRec.uid, uidRec);
22149                            }
22150                        }
22151                    }
22152                }
22153            } finally {
22154                if (mLocalPowerManager != null) {
22155                    mLocalPowerManager.finishUidChanges();
22156                }
22157                Binder.restoreCallingIdentity(callingId);
22158            }
22159        }
22160    }
22161
22162    final void idleUids() {
22163        synchronized (this) {
22164            final int N = mActiveUids.size();
22165            if (N <= 0) {
22166                return;
22167            }
22168            final long nowElapsed = SystemClock.elapsedRealtime();
22169            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
22170            long nextTime = 0;
22171            if (mLocalPowerManager != null) {
22172                mLocalPowerManager.startUidChanges();
22173            }
22174            for (int i=N-1; i>=0; i--) {
22175                final UidRecord uidRec = mActiveUids.valueAt(i);
22176                final long bgTime = uidRec.lastBackgroundTime;
22177                if (bgTime > 0 && !uidRec.idle) {
22178                    if (bgTime <= maxBgTime) {
22179                        uidRec.idle = true;
22180                        doStopUidLocked(uidRec.uid, uidRec);
22181                    } else {
22182                        if (nextTime == 0 || nextTime > bgTime) {
22183                            nextTime = bgTime;
22184                        }
22185                    }
22186                }
22187            }
22188            if (mLocalPowerManager != null) {
22189                mLocalPowerManager.finishUidChanges();
22190            }
22191            if (nextTime > 0) {
22192                mHandler.removeMessages(IDLE_UIDS_MSG);
22193                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
22194                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
22195            }
22196        }
22197    }
22198
22199    /**
22200     * If {@link UidRecord#curProcStateSeq} needs to be updated, then increments the global seq
22201     * counter {@link #mProcStateSeqCounter} and uses that value for {@param uidRec}.
22202     */
22203    @VisibleForTesting
22204    void incrementProcStateSeqIfNeeded(UidRecord uidRec) {
22205        if (uidRec.curProcState != uidRec.setProcState && shouldIncrementProcStateSeq(uidRec)) {
22206            uidRec.curProcStateSeq = ++mProcStateSeqCounter;
22207        }
22208    }
22209
22210    /**
22211     * Checks if {@link UidRecord#curProcStateSeq} needs to be incremented depending on whether
22212     * the uid is coming from background to foreground state or vice versa.
22213     *
22214     * @return Returns true if the uid is coming from background to foreground state or vice versa,
22215     *                 false otherwise.
22216     */
22217    @VisibleForTesting
22218    boolean shouldIncrementProcStateSeq(UidRecord uidRec) {
22219        final boolean isAllowedOnRestrictBackground
22220                = isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState);
22221        final boolean isAllowedOnDeviceIdleOrPowerSaveMode
22222                = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState);
22223
22224        final boolean wasAllowedOnRestrictBackground
22225                = isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
22226        final boolean wasAllowedOnDeviceIdleOrPowerSaveMode
22227                = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState);
22228
22229        // If the uid is coming from background to foreground or vice versa,
22230        // then return true. Otherwise false.
22231        return (wasAllowedOnDeviceIdleOrPowerSaveMode != isAllowedOnDeviceIdleOrPowerSaveMode)
22232                || (wasAllowedOnRestrictBackground != isAllowedOnRestrictBackground);
22233    }
22234
22235    final void runInBackgroundDisabled(int uid) {
22236        synchronized (this) {
22237            UidRecord uidRec = mActiveUids.get(uid);
22238            if (uidRec != null) {
22239                // This uid is actually running...  should it be considered background now?
22240                if (uidRec.idle) {
22241                    doStopUidLocked(uidRec.uid, uidRec);
22242                }
22243            } else {
22244                // This uid isn't actually running...  still send a report about it being "stopped".
22245                doStopUidLocked(uid, null);
22246            }
22247        }
22248    }
22249
22250    final void doStopUidLocked(int uid, final UidRecord uidRec) {
22251        mServices.stopInBackgroundLocked(uid);
22252        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
22253    }
22254
22255    final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) {
22256        boolean changed = false;
22257        for (int i=mActiveUids.size()-1; i>=0; i--) {
22258            final UidRecord uidRec = mActiveUids.valueAt(i);
22259            if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) {
22260                uidRec.curWhitelist = onWhitelist;
22261                changed = true;
22262            }
22263        }
22264        if (changed) {
22265            updateOomAdjLocked();
22266        }
22267    }
22268
22269    final void trimApplications() {
22270        synchronized (this) {
22271            int i;
22272
22273            // First remove any unused application processes whose package
22274            // has been removed.
22275            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
22276                final ProcessRecord app = mRemovedProcesses.get(i);
22277                if (app.activities.size() == 0
22278                        && app.curReceivers.isEmpty() && app.services.size() == 0) {
22279                    Slog.i(
22280                        TAG, "Exiting empty application process "
22281                        + app.toShortString() + " ("
22282                        + (app.thread != null ? app.thread.asBinder() : null)
22283                        + ")\n");
22284                    if (app.pid > 0 && app.pid != MY_PID) {
22285                        app.kill("empty", false);
22286                    } else {
22287                        try {
22288                            app.thread.scheduleExit();
22289                        } catch (Exception e) {
22290                            // Ignore exceptions.
22291                        }
22292                    }
22293                    cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
22294                    mRemovedProcesses.remove(i);
22295
22296                    if (app.persistent) {
22297                        addAppLocked(app.info, null, false, null /* ABI override */);
22298                    }
22299                }
22300            }
22301
22302            // Now update the oom adj for all processes.
22303            updateOomAdjLocked();
22304        }
22305    }
22306
22307    /** This method sends the specified signal to each of the persistent apps */
22308    public void signalPersistentProcesses(int sig) throws RemoteException {
22309        if (sig != Process.SIGNAL_USR1) {
22310            throw new SecurityException("Only SIGNAL_USR1 is allowed");
22311        }
22312
22313        synchronized (this) {
22314            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
22315                    != PackageManager.PERMISSION_GRANTED) {
22316                throw new SecurityException("Requires permission "
22317                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
22318            }
22319
22320            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
22321                ProcessRecord r = mLruProcesses.get(i);
22322                if (r.thread != null && r.persistent) {
22323                    Process.sendSignal(r.pid, sig);
22324                }
22325            }
22326        }
22327    }
22328
22329    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
22330        if (proc == null || proc == mProfileProc) {
22331            proc = mProfileProc;
22332            profileType = mProfileType;
22333            clearProfilerLocked();
22334        }
22335        if (proc == null) {
22336            return;
22337        }
22338        try {
22339            proc.thread.profilerControl(false, null, profileType);
22340        } catch (RemoteException e) {
22341            throw new IllegalStateException("Process disappeared");
22342        }
22343    }
22344
22345    private void clearProfilerLocked() {
22346        if (mProfileFd != null) {
22347            try {
22348                mProfileFd.close();
22349            } catch (IOException e) {
22350            }
22351        }
22352        mProfileApp = null;
22353        mProfileProc = null;
22354        mProfileFile = null;
22355        mProfileType = 0;
22356        mAutoStopProfiler = false;
22357        mStreamingOutput = false;
22358        mSamplingInterval = 0;
22359    }
22360
22361    public boolean profileControl(String process, int userId, boolean start,
22362            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
22363
22364        try {
22365            synchronized (this) {
22366                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
22367                // its own permission.
22368                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
22369                        != PackageManager.PERMISSION_GRANTED) {
22370                    throw new SecurityException("Requires permission "
22371                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
22372                }
22373
22374                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
22375                    throw new IllegalArgumentException("null profile info or fd");
22376                }
22377
22378                ProcessRecord proc = null;
22379                if (process != null) {
22380                    proc = findProcessLocked(process, userId, "profileControl");
22381                }
22382
22383                if (start && (proc == null || proc.thread == null)) {
22384                    throw new IllegalArgumentException("Unknown process: " + process);
22385                }
22386
22387                if (start) {
22388                    stopProfilerLocked(null, 0);
22389                    setProfileApp(proc.info, proc.processName, profilerInfo);
22390                    mProfileProc = proc;
22391                    mProfileType = profileType;
22392                    ParcelFileDescriptor fd = profilerInfo.profileFd;
22393                    try {
22394                        fd = fd.dup();
22395                    } catch (IOException e) {
22396                        fd = null;
22397                    }
22398                    profilerInfo.profileFd = fd;
22399                    proc.thread.profilerControl(start, profilerInfo, profileType);
22400                    fd = null;
22401                    try {
22402                        mProfileFd.close();
22403                    } catch (IOException e) {
22404                    }
22405                    mProfileFd = null;
22406                } else {
22407                    stopProfilerLocked(proc, profileType);
22408                    if (profilerInfo != null && profilerInfo.profileFd != null) {
22409                        try {
22410                            profilerInfo.profileFd.close();
22411                        } catch (IOException e) {
22412                        }
22413                    }
22414                }
22415
22416                return true;
22417            }
22418        } catch (RemoteException e) {
22419            throw new IllegalStateException("Process disappeared");
22420        } finally {
22421            if (profilerInfo != null && profilerInfo.profileFd != null) {
22422                try {
22423                    profilerInfo.profileFd.close();
22424                } catch (IOException e) {
22425                }
22426            }
22427        }
22428    }
22429
22430    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
22431        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
22432                userId, true, ALLOW_FULL_ONLY, callName, null);
22433        ProcessRecord proc = null;
22434        try {
22435            int pid = Integer.parseInt(process);
22436            synchronized (mPidsSelfLocked) {
22437                proc = mPidsSelfLocked.get(pid);
22438            }
22439        } catch (NumberFormatException e) {
22440        }
22441
22442        if (proc == null) {
22443            ArrayMap<String, SparseArray<ProcessRecord>> all
22444                    = mProcessNames.getMap();
22445            SparseArray<ProcessRecord> procs = all.get(process);
22446            if (procs != null && procs.size() > 0) {
22447                proc = procs.valueAt(0);
22448                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
22449                    for (int i=1; i<procs.size(); i++) {
22450                        ProcessRecord thisProc = procs.valueAt(i);
22451                        if (thisProc.userId == userId) {
22452                            proc = thisProc;
22453                            break;
22454                        }
22455                    }
22456                }
22457            }
22458        }
22459
22460        return proc;
22461    }
22462
22463    public boolean dumpHeap(String process, int userId, boolean managed,
22464            String path, ParcelFileDescriptor fd) throws RemoteException {
22465
22466        try {
22467            synchronized (this) {
22468                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
22469                // its own permission (same as profileControl).
22470                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
22471                        != PackageManager.PERMISSION_GRANTED) {
22472                    throw new SecurityException("Requires permission "
22473                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
22474                }
22475
22476                if (fd == null) {
22477                    throw new IllegalArgumentException("null fd");
22478                }
22479
22480                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
22481                if (proc == null || proc.thread == null) {
22482                    throw new IllegalArgumentException("Unknown process: " + process);
22483                }
22484
22485                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
22486                if (!isDebuggable) {
22487                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
22488                        throw new SecurityException("Process not debuggable: " + proc);
22489                    }
22490                }
22491
22492                proc.thread.dumpHeap(managed, path, fd);
22493                fd = null;
22494                return true;
22495            }
22496        } catch (RemoteException e) {
22497            throw new IllegalStateException("Process disappeared");
22498        } finally {
22499            if (fd != null) {
22500                try {
22501                    fd.close();
22502                } catch (IOException e) {
22503                }
22504            }
22505        }
22506    }
22507
22508    @Override
22509    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
22510            String reportPackage) {
22511        if (processName != null) {
22512            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
22513                    "setDumpHeapDebugLimit()");
22514        } else {
22515            synchronized (mPidsSelfLocked) {
22516                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
22517                if (proc == null) {
22518                    throw new SecurityException("No process found for calling pid "
22519                            + Binder.getCallingPid());
22520                }
22521                if (!Build.IS_DEBUGGABLE
22522                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
22523                    throw new SecurityException("Not running a debuggable build");
22524                }
22525                processName = proc.processName;
22526                uid = proc.uid;
22527                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
22528                    throw new SecurityException("Package " + reportPackage + " is not running in "
22529                            + proc);
22530                }
22531            }
22532        }
22533        synchronized (this) {
22534            if (maxMemSize > 0) {
22535                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
22536            } else {
22537                if (uid != 0) {
22538                    mMemWatchProcesses.remove(processName, uid);
22539                } else {
22540                    mMemWatchProcesses.getMap().remove(processName);
22541                }
22542            }
22543        }
22544    }
22545
22546    @Override
22547    public void dumpHeapFinished(String path) {
22548        synchronized (this) {
22549            if (Binder.getCallingPid() != mMemWatchDumpPid) {
22550                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
22551                        + " does not match last pid " + mMemWatchDumpPid);
22552                return;
22553            }
22554            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
22555                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
22556                        + " does not match last path " + mMemWatchDumpFile);
22557                return;
22558            }
22559            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
22560            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
22561        }
22562    }
22563
22564    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
22565    public void monitor() {
22566        synchronized (this) { }
22567    }
22568
22569    void onCoreSettingsChange(Bundle settings) {
22570        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
22571            ProcessRecord processRecord = mLruProcesses.get(i);
22572            try {
22573                if (processRecord.thread != null) {
22574                    processRecord.thread.setCoreSettings(settings);
22575                }
22576            } catch (RemoteException re) {
22577                /* ignore */
22578            }
22579        }
22580    }
22581
22582    // Multi-user methods
22583
22584    /**
22585     * Start user, if its not already running, but don't bring it to foreground.
22586     */
22587    @Override
22588    public boolean startUserInBackground(final int userId) {
22589        return mUserController.startUser(userId, /* foreground */ false);
22590    }
22591
22592    @Override
22593    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
22594        return mUserController.unlockUser(userId, token, secret, listener);
22595    }
22596
22597    @Override
22598    public boolean switchUser(final int targetUserId) {
22599        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
22600        int currentUserId;
22601        UserInfo targetUserInfo;
22602        synchronized (this) {
22603            currentUserId = mUserController.getCurrentUserIdLocked();
22604            targetUserInfo = mUserController.getUserInfo(targetUserId);
22605            if (targetUserId == currentUserId) {
22606                Slog.i(TAG, "user #" + targetUserId + " is already the current user");
22607                return true;
22608            }
22609            if (targetUserInfo == null) {
22610                Slog.w(TAG, "No user info for user #" + targetUserId);
22611                return false;
22612            }
22613            if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
22614                Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
22615                        + " when device is in demo mode");
22616                return false;
22617            }
22618            if (!targetUserInfo.supportsSwitchTo()) {
22619                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
22620                return false;
22621            }
22622            if (targetUserInfo.isManagedProfile()) {
22623                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
22624                return false;
22625            }
22626            mUserController.setTargetUserIdLocked(targetUserId);
22627        }
22628        if (mUserController.mUserSwitchUiEnabled) {
22629            UserInfo currentUserInfo = mUserController.getUserInfo(currentUserId);
22630            Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
22631            mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
22632            mUiHandler.sendMessage(mHandler.obtainMessage(
22633                    START_USER_SWITCH_UI_MSG, userNames));
22634        } else {
22635            mHandler.removeMessages(START_USER_SWITCH_FG_MSG);
22636            mHandler.sendMessage(mHandler.obtainMessage(
22637                    START_USER_SWITCH_FG_MSG, targetUserId, 0));
22638        }
22639        return true;
22640    }
22641
22642    void scheduleStartProfilesLocked() {
22643        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
22644            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
22645                    DateUtils.SECOND_IN_MILLIS);
22646        }
22647    }
22648
22649    @Override
22650    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
22651        return mUserController.stopUser(userId, force, callback);
22652    }
22653
22654    @Override
22655    public UserInfo getCurrentUser() {
22656        return mUserController.getCurrentUser();
22657    }
22658
22659    String getStartedUserState(int userId) {
22660        synchronized (this) {
22661            final UserState userState = mUserController.getStartedUserStateLocked(userId);
22662            return UserState.stateToString(userState.state);
22663        }
22664    }
22665
22666    @Override
22667    public boolean isUserRunning(int userId, int flags) {
22668        if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
22669                && checkCallingPermission(INTERACT_ACROSS_USERS)
22670                    != PackageManager.PERMISSION_GRANTED) {
22671            String msg = "Permission Denial: isUserRunning() from pid="
22672                    + Binder.getCallingPid()
22673                    + ", uid=" + Binder.getCallingUid()
22674                    + " requires " + INTERACT_ACROSS_USERS;
22675            Slog.w(TAG, msg);
22676            throw new SecurityException(msg);
22677        }
22678        synchronized (this) {
22679            return mUserController.isUserRunningLocked(userId, flags);
22680        }
22681    }
22682
22683    @Override
22684    public int[] getRunningUserIds() {
22685        if (checkCallingPermission(INTERACT_ACROSS_USERS)
22686                != PackageManager.PERMISSION_GRANTED) {
22687            String msg = "Permission Denial: isUserRunning() from pid="
22688                    + Binder.getCallingPid()
22689                    + ", uid=" + Binder.getCallingUid()
22690                    + " requires " + INTERACT_ACROSS_USERS;
22691            Slog.w(TAG, msg);
22692            throw new SecurityException(msg);
22693        }
22694        synchronized (this) {
22695            return mUserController.getStartedUserArrayLocked();
22696        }
22697    }
22698
22699    @Override
22700    public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
22701        mUserController.registerUserSwitchObserver(observer, name);
22702    }
22703
22704    @Override
22705    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
22706        mUserController.unregisterUserSwitchObserver(observer);
22707    }
22708
22709    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
22710        if (info == null) return null;
22711        ApplicationInfo newInfo = new ApplicationInfo(info);
22712        newInfo.initForUser(userId);
22713        return newInfo;
22714    }
22715
22716    public boolean isUserStopped(int userId) {
22717        synchronized (this) {
22718            return mUserController.getStartedUserStateLocked(userId) == null;
22719        }
22720    }
22721
22722    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
22723        if (aInfo == null
22724                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
22725            return aInfo;
22726        }
22727
22728        ActivityInfo info = new ActivityInfo(aInfo);
22729        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
22730        return info;
22731    }
22732
22733    private boolean processSanityChecksLocked(ProcessRecord process) {
22734        if (process == null || process.thread == null) {
22735            return false;
22736        }
22737
22738        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
22739        if (!isDebuggable) {
22740            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
22741                return false;
22742            }
22743        }
22744
22745        return true;
22746    }
22747
22748    public boolean startBinderTracking() throws RemoteException {
22749        synchronized (this) {
22750            mBinderTransactionTrackingEnabled = true;
22751            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
22752            // permission (same as profileControl).
22753            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
22754                    != PackageManager.PERMISSION_GRANTED) {
22755                throw new SecurityException("Requires permission "
22756                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
22757            }
22758
22759            for (int i = 0; i < mLruProcesses.size(); i++) {
22760                ProcessRecord process = mLruProcesses.get(i);
22761                if (!processSanityChecksLocked(process)) {
22762                    continue;
22763                }
22764                try {
22765                    process.thread.startBinderTracking();
22766                } catch (RemoteException e) {
22767                    Log.v(TAG, "Process disappared");
22768                }
22769            }
22770            return true;
22771        }
22772    }
22773
22774    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
22775        try {
22776            synchronized (this) {
22777                mBinderTransactionTrackingEnabled = false;
22778                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
22779                // permission (same as profileControl).
22780                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
22781                        != PackageManager.PERMISSION_GRANTED) {
22782                    throw new SecurityException("Requires permission "
22783                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
22784                }
22785
22786                if (fd == null) {
22787                    throw new IllegalArgumentException("null fd");
22788                }
22789
22790                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
22791                pw.println("Binder transaction traces for all processes.\n");
22792                for (ProcessRecord process : mLruProcesses) {
22793                    if (!processSanityChecksLocked(process)) {
22794                        continue;
22795                    }
22796
22797                    pw.println("Traces for process: " + process.processName);
22798                    pw.flush();
22799                    try {
22800                        TransferPipe tp = new TransferPipe();
22801                        try {
22802                            process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
22803                            tp.go(fd.getFileDescriptor());
22804                        } finally {
22805                            tp.kill();
22806                        }
22807                    } catch (IOException e) {
22808                        pw.println("Failure while dumping IPC traces from " + process +
22809                                ".  Exception: " + e);
22810                        pw.flush();
22811                    } catch (RemoteException e) {
22812                        pw.println("Got a RemoteException while dumping IPC traces from " +
22813                                process + ".  Exception: " + e);
22814                        pw.flush();
22815                    }
22816                }
22817                fd = null;
22818                return true;
22819            }
22820        } finally {
22821            if (fd != null) {
22822                try {
22823                    fd.close();
22824                } catch (IOException e) {
22825                }
22826            }
22827        }
22828    }
22829
22830    private final class LocalService extends ActivityManagerInternal {
22831        @Override
22832        public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
22833                int targetUserId) {
22834            synchronized (ActivityManagerService.this) {
22835                ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
22836                        targetPkg, intent, null, targetUserId);
22837            }
22838        }
22839
22840        @Override
22841        public String checkContentProviderAccess(String authority, int userId) {
22842            return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
22843        }
22844
22845        @Override
22846        public void onWakefulnessChanged(int wakefulness) {
22847            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
22848        }
22849
22850        @Override
22851        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
22852                String processName, String abiOverride, int uid, Runnable crashHandler) {
22853            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
22854                    processName, abiOverride, uid, crashHandler);
22855        }
22856
22857        @Override
22858        public SleepToken acquireSleepToken(String tag) {
22859            Preconditions.checkNotNull(tag);
22860
22861            synchronized (ActivityManagerService.this) {
22862                SleepTokenImpl token = new SleepTokenImpl(tag);
22863                mSleepTokens.add(token);
22864                updateSleepIfNeededLocked();
22865                return token;
22866            }
22867        }
22868
22869        @Override
22870        public ComponentName getHomeActivityForUser(int userId) {
22871            synchronized (ActivityManagerService.this) {
22872                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
22873                return homeActivity == null ? null : homeActivity.realActivity;
22874            }
22875        }
22876
22877        @Override
22878        public void onUserRemoved(int userId) {
22879            synchronized (ActivityManagerService.this) {
22880                ActivityManagerService.this.onUserStoppedLocked(userId);
22881            }
22882        }
22883
22884        @Override
22885        public void onLocalVoiceInteractionStarted(IBinder activity,
22886                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
22887            synchronized (ActivityManagerService.this) {
22888                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
22889                        voiceSession, voiceInteractor);
22890            }
22891        }
22892
22893        @Override
22894        public void notifyStartingWindowDrawn() {
22895            synchronized (ActivityManagerService.this) {
22896                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
22897            }
22898        }
22899
22900        @Override
22901        public void notifyAppTransitionStarting(int reason) {
22902            synchronized (ActivityManagerService.this) {
22903                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
22904            }
22905        }
22906
22907        @Override
22908        public void notifyAppTransitionFinished() {
22909            synchronized (ActivityManagerService.this) {
22910                mStackSupervisor.notifyAppTransitionDone();
22911            }
22912        }
22913
22914        @Override
22915        public void notifyAppTransitionCancelled() {
22916            synchronized (ActivityManagerService.this) {
22917                mStackSupervisor.notifyAppTransitionDone();
22918            }
22919        }
22920
22921        @Override
22922        public List<IBinder> getTopVisibleActivities() {
22923            synchronized (ActivityManagerService.this) {
22924                return mStackSupervisor.getTopVisibleActivities();
22925            }
22926        }
22927
22928        @Override
22929        public void notifyDockedStackMinimizedChanged(boolean minimized) {
22930            synchronized (ActivityManagerService.this) {
22931                mStackSupervisor.setDockedStackMinimized(minimized);
22932            }
22933        }
22934
22935        @Override
22936        public void killForegroundAppsForUser(int userHandle) {
22937            synchronized (ActivityManagerService.this) {
22938                final ArrayList<ProcessRecord> procs = new ArrayList<>();
22939                final int NP = mProcessNames.getMap().size();
22940                for (int ip = 0; ip < NP; ip++) {
22941                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
22942                    final int NA = apps.size();
22943                    for (int ia = 0; ia < NA; ia++) {
22944                        final ProcessRecord app = apps.valueAt(ia);
22945                        if (app.persistent) {
22946                            // We don't kill persistent processes.
22947                            continue;
22948                        }
22949                        if (app.removed) {
22950                            procs.add(app);
22951                        } else if (app.userId == userHandle && app.foregroundActivities) {
22952                            app.removed = true;
22953                            procs.add(app);
22954                        }
22955                    }
22956                }
22957
22958                final int N = procs.size();
22959                for (int i = 0; i < N; i++) {
22960                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
22961                }
22962            }
22963        }
22964
22965        @Override
22966        public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
22967            if (!(target instanceof PendingIntentRecord)) {
22968                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
22969                return;
22970            }
22971            ((PendingIntentRecord) target).setWhitelistDuration(duration);
22972        }
22973
22974        @Override
22975        public void setDeviceIdleWhitelist(int[] appids) {
22976            synchronized (ActivityManagerService.this) {
22977                mDeviceIdleWhitelist = appids;
22978            }
22979        }
22980
22981        @Override
22982        public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) {
22983            synchronized (ActivityManagerService.this) {
22984                mDeviceIdleTempWhitelist = appids;
22985                setAppIdTempWhitelistStateLocked(changingAppId, adding);
22986            }
22987        }
22988
22989        @Override
22990        public void updatePersistentConfigurationForUser(@NonNull Configuration values,
22991                int userId) {
22992            Preconditions.checkNotNull(values, "Configuration must not be null");
22993            Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
22994            synchronized (ActivityManagerService.this) {
22995                updateConfigurationLocked(values, null, false, true, userId,
22996                        false /* deferResume */);
22997            }
22998        }
22999
23000        @Override
23001        public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
23002                Bundle bOptions) {
23003            Preconditions.checkNotNull(intents, "intents");
23004            final String[] resolvedTypes = new String[intents.length];
23005            for (int i = 0; i < intents.length; i++) {
23006                resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
23007            }
23008
23009            // UID of the package on user userId.
23010            // "= 0" is needed because otherwise catch(RemoteException) would make it look like
23011            // packageUid may not be initialized.
23012            int packageUid = 0;
23013            try {
23014                packageUid = AppGlobals.getPackageManager().getPackageUid(
23015                        packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
23016            } catch (RemoteException e) {
23017                // Shouldn't happen.
23018            }
23019
23020            synchronized (ActivityManagerService.this) {
23021                return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
23022                        /*resultTo*/ null, bOptions, userId);
23023            }
23024        }
23025
23026        @Override
23027        public int getUidProcessState(int uid) {
23028            return getUidState(uid);
23029        }
23030
23031        @Override
23032        public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
23033            synchronized (ActivityManagerService.this) {
23034
23035                // We might change the visibilities here, so prepare an empty app transition which
23036                // might be overridden later if we actually change visibilities.
23037                mWindowManager.prepareAppTransition(TRANSIT_NONE, false /* alwaysKeepCurrent */);
23038                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
23039                mWindowManager.executeAppTransition();
23040            }
23041            if (callback != null) {
23042                callback.run();
23043            }
23044        }
23045
23046        @Override
23047        public boolean isSystemReady() {
23048            // no need to synchronize(this) just to read & return the value
23049            return mSystemReady;
23050        }
23051
23052        @Override
23053        public void notifyKeyguardTrustedChanged() {
23054            synchronized (ActivityManagerService.this) {
23055                if (mKeyguardController.isKeyguardShowing()) {
23056                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
23057                }
23058            }
23059        }
23060
23061        /**
23062         * Sets if the given pid has an overlay UI or not.
23063         *
23064         * @param pid The pid we are setting overlay UI for.
23065         * @param hasOverlayUi True if the process has overlay UI.
23066         * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
23067         */
23068        @Override
23069        public void setHasOverlayUi(int pid, boolean hasOverlayUi) {
23070            synchronized (ActivityManagerService.this) {
23071                final ProcessRecord pr;
23072                synchronized (mPidsSelfLocked) {
23073                    pr = mPidsSelfLocked.get(pid);
23074                    if (pr == null) {
23075                        Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid);
23076                        return;
23077                    }
23078                }
23079                if (pr.hasOverlayUi == hasOverlayUi) {
23080                    return;
23081                }
23082                pr.hasOverlayUi = hasOverlayUi;
23083                //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
23084                updateOomAdjLocked(pr);
23085            }
23086        }
23087    }
23088
23089    private final class SleepTokenImpl extends SleepToken {
23090        private final String mTag;
23091        private final long mAcquireTime;
23092
23093        public SleepTokenImpl(String tag) {
23094            mTag = tag;
23095            mAcquireTime = SystemClock.uptimeMillis();
23096        }
23097
23098        @Override
23099        public void release() {
23100            synchronized (ActivityManagerService.this) {
23101                if (mSleepTokens.remove(this)) {
23102                    updateSleepIfNeededLocked();
23103                }
23104            }
23105        }
23106
23107        @Override
23108        public String toString() {
23109            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
23110        }
23111    }
23112
23113    /**
23114     * An implementation of IAppTask, that allows an app to manage its own tasks via
23115     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
23116     * only the process that calls getAppTasks() can call the AppTask methods.
23117     */
23118    class AppTaskImpl extends IAppTask.Stub {
23119        private int mTaskId;
23120        private int mCallingUid;
23121
23122        public AppTaskImpl(int taskId, int callingUid) {
23123            mTaskId = taskId;
23124            mCallingUid = callingUid;
23125        }
23126
23127        private void checkCaller() {
23128            if (mCallingUid != Binder.getCallingUid()) {
23129                throw new SecurityException("Caller " + mCallingUid
23130                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
23131            }
23132        }
23133
23134        @Override
23135        public void finishAndRemoveTask() {
23136            checkCaller();
23137
23138            synchronized (ActivityManagerService.this) {
23139                long origId = Binder.clearCallingIdentity();
23140                try {
23141                    // We remove the task from recents to preserve backwards
23142                    if (!mStackSupervisor.removeTaskByIdLocked(mTaskId, false,
23143                            REMOVE_FROM_RECENTS)) {
23144                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
23145                    }
23146                } finally {
23147                    Binder.restoreCallingIdentity(origId);
23148                }
23149            }
23150        }
23151
23152        @Override
23153        public ActivityManager.RecentTaskInfo getTaskInfo() {
23154            checkCaller();
23155
23156            synchronized (ActivityManagerService.this) {
23157                long origId = Binder.clearCallingIdentity();
23158                try {
23159                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
23160                    if (tr == null) {
23161                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
23162                    }
23163                    return createRecentTaskInfoFromTaskRecord(tr);
23164                } finally {
23165                    Binder.restoreCallingIdentity(origId);
23166                }
23167            }
23168        }
23169
23170        @Override
23171        public void moveToFront() {
23172            checkCaller();
23173            // Will bring task to front if it already has a root activity.
23174            final long origId = Binder.clearCallingIdentity();
23175            try {
23176                synchronized (this) {
23177                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
23178                }
23179            } finally {
23180                Binder.restoreCallingIdentity(origId);
23181            }
23182        }
23183
23184        @Override
23185        public int startActivity(IBinder whoThread, String callingPackage,
23186                Intent intent, String resolvedType, Bundle bOptions) {
23187            checkCaller();
23188
23189            int callingUser = UserHandle.getCallingUserId();
23190            TaskRecord tr;
23191            IApplicationThread appThread;
23192            synchronized (ActivityManagerService.this) {
23193                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
23194                if (tr == null) {
23195                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
23196                }
23197                appThread = IApplicationThread.Stub.asInterface(whoThread);
23198                if (appThread == null) {
23199                    throw new IllegalArgumentException("Bad app thread " + appThread);
23200                }
23201            }
23202            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
23203                    resolvedType, null, null, null, null, 0, 0, null, null,
23204                    null, bOptions, false, callingUser, null, tr);
23205        }
23206
23207        @Override
23208        public void setExcludeFromRecents(boolean exclude) {
23209            checkCaller();
23210
23211            synchronized (ActivityManagerService.this) {
23212                long origId = Binder.clearCallingIdentity();
23213                try {
23214                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
23215                    if (tr == null) {
23216                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
23217                    }
23218                    Intent intent = tr.getBaseIntent();
23219                    if (exclude) {
23220                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
23221                    } else {
23222                        intent.setFlags(intent.getFlags()
23223                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
23224                    }
23225                } finally {
23226                    Binder.restoreCallingIdentity(origId);
23227                }
23228            }
23229        }
23230    }
23231
23232    /**
23233     * Kill processes for the user with id userId and that depend on the package named packageName
23234     */
23235    @Override
23236    public void killPackageDependents(String packageName, int userId) {
23237        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
23238        if (packageName == null) {
23239            throw new NullPointerException(
23240                    "Cannot kill the dependents of a package without its name.");
23241        }
23242
23243        long callingId = Binder.clearCallingIdentity();
23244        IPackageManager pm = AppGlobals.getPackageManager();
23245        int pkgUid = -1;
23246        try {
23247            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
23248        } catch (RemoteException e) {
23249        }
23250        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
23251            throw new IllegalArgumentException(
23252                    "Cannot kill dependents of non-existing package " + packageName);
23253        }
23254        try {
23255            synchronized(this) {
23256                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
23257                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
23258                        "dep: " + packageName);
23259            }
23260        } finally {
23261            Binder.restoreCallingIdentity(callingId);
23262        }
23263    }
23264
23265    @Override
23266    public boolean canBypassWorkChallenge(PendingIntent intent) throws RemoteException {
23267        final int userId = intent.getCreatorUserHandle().getIdentifier();
23268        if (!mUserController.isUserRunningLocked(userId, ActivityManager.FLAG_AND_LOCKED)) {
23269            return false;
23270        }
23271        IIntentSender target = intent.getTarget();
23272        if (!(target instanceof PendingIntentRecord)) {
23273            return false;
23274        }
23275        final PendingIntentRecord record = (PendingIntentRecord) target;
23276        final ResolveInfo rInfo = mStackSupervisor.resolveIntent(record.key.requestIntent,
23277                record.key.requestResolvedType, userId, PackageManager.MATCH_DIRECT_BOOT_AWARE);
23278        // For direct boot aware activities, they can be shown without triggering a work challenge
23279        // before the profile user is unlocked.
23280        return rInfo != null && rInfo.activityInfo != null;
23281    }
23282
23283    @Override
23284    public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback)
23285            throws RemoteException {
23286        final long callingId = Binder.clearCallingIdentity();
23287        try {
23288            mKeyguardController.dismissKeyguard(token, callback);
23289        } finally {
23290            Binder.restoreCallingIdentity(callingId);
23291        }
23292    }
23293
23294    @Override
23295    public int restartUserInBackground(final int userId) {
23296        return mUserController.restartUser(userId, /* foreground */ false);
23297    }
23298
23299    @Override
23300    public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) {
23301        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
23302                "scheduleApplicationInfoChanged()");
23303
23304        synchronized (this) {
23305            final long origId = Binder.clearCallingIdentity();
23306            try {
23307                updateApplicationInfoLocked(packageNames, userId);
23308            } finally {
23309                Binder.restoreCallingIdentity(origId);
23310            }
23311        }
23312    }
23313
23314    void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) {
23315        final PackageManagerInternal packageManager = getPackageManagerInternalLocked();
23316        final boolean updateFrameworkRes = packagesToUpdate.contains("android");
23317        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
23318            final ProcessRecord app = mLruProcesses.get(i);
23319            if (app.thread == null || app.pid == Process.myPid()) {
23320                continue;
23321            }
23322
23323            if (userId != UserHandle.USER_ALL && app.userId != userId) {
23324                continue;
23325            }
23326
23327            final int packageCount = app.pkgList.size();
23328            for (int j = 0; j < packageCount; j++) {
23329                final String packageName = app.pkgList.keyAt(j);
23330                if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
23331                    try {
23332                        final ApplicationInfo ai = packageManager.getApplicationInfo(
23333                                packageName, app.userId);
23334                        if (ai != null) {
23335                            app.thread.scheduleApplicationInfoChanged(ai);
23336                        }
23337                    } catch (RemoteException e) {
23338                        Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
23339                                    packageName, app));
23340                    }
23341                }
23342            }
23343        }
23344    }
23345
23346    /**
23347     * Attach an agent to the specified process (proces name or PID)
23348     */
23349    public void attachAgent(String process, String path) {
23350        try {
23351            synchronized (this) {
23352                ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
23353                if (proc == null || proc.thread == null) {
23354                    throw new IllegalArgumentException("Unknown process: " + process);
23355                }
23356
23357                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23358                if (!isDebuggable) {
23359                    if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23360                        throw new SecurityException("Process not debuggable: " + proc);
23361                    }
23362                }
23363
23364                proc.thread.attachAgent(path);
23365            }
23366        } catch (RemoteException e) {
23367            throw new IllegalStateException("Process disappeared");
23368        }
23369    }
23370}
23371