ActivityManagerService.java revision f764962b0d58008530955b70af1ebf68beb8d4ba
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.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
51import static android.provider.Settings.Global.DEBUG_APP;
52import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
53import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
54import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
55import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
56import static android.provider.Settings.System.FONT_SCALE;
57import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
58import static android.view.Display.DEFAULT_DISPLAY;
59import static com.android.internal.util.XmlUtils.readBooleanAttribute;
60import static com.android.internal.util.XmlUtils.readIntAttribute;
61import static com.android.internal.util.XmlUtils.readLongAttribute;
62import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
63import static com.android.internal.util.XmlUtils.writeIntAttribute;
64import static com.android.internal.util.XmlUtils.writeLongAttribute;
65import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
66import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
67import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKGROUND_CHECK;
68import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
69import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
70import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
71import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
72import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
73import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
74import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
75import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
76import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
77import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
78import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
79import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
80import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
81import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
82import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
83import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
84import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
85import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
86import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
87import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
88import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
89import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
90import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
91import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
92import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
93import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
94import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
95import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
96import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
97import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
98import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
99import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
100import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
101import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
102import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
103import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
104import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
105import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
106import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
107import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
108import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
109import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
110import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
111import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
112import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
113import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
114import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
115import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
116import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
117import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
118import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
119import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
120import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
121import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
122import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
123import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
124import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
125import static com.android.server.am.ActivityStackSupervisor.CREATE_IF_NEEDED;
126import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
127import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
128import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
129import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
130import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
131import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
132import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
133import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
134import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
135import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
136import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
137import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
138import static com.android.server.wm.AppTransition.TRANSIT_NONE;
139import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
140import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
141import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
142import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
143import static org.xmlpull.v1.XmlPullParser.START_TAG;
144
145import android.Manifest;
146import android.Manifest.permission;
147import android.annotation.NonNull;
148import android.annotation.Nullable;
149import android.annotation.UserIdInt;
150import android.app.Activity;
151import android.app.ActivityManager;
152import android.app.ActivityManager.RunningTaskInfo;
153import android.app.ActivityManager.StackId;
154import android.app.ActivityManager.StackInfo;
155import android.app.ActivityManager.TaskSnapshot;
156import android.app.ActivityManager.TaskThumbnailInfo;
157import android.app.ActivityManagerInternal;
158import android.app.ActivityManagerInternal.SleepToken;
159import android.app.ActivityOptions;
160import android.app.ActivityThread;
161import android.app.AlertDialog;
162import android.app.AppGlobals;
163import android.app.AppOpsManager;
164import android.app.ApplicationErrorReport;
165import android.app.ApplicationThreadConstants;
166import android.app.BroadcastOptions;
167import android.app.ContentProviderHolder;
168import android.app.Dialog;
169import android.app.IActivityContainer;
170import android.app.IActivityContainerCallback;
171import android.app.IActivityController;
172import android.app.IActivityManager;
173import android.app.IAppTask;
174import android.app.IApplicationThread;
175import android.app.IInstrumentationWatcher;
176import android.app.INotificationManager;
177import android.app.IProcessObserver;
178import android.app.IServiceConnection;
179import android.app.IStopUserCallback;
180import android.app.ITaskStackListener;
181import android.app.IUiAutomationConnection;
182import android.app.IUidObserver;
183import android.app.IUserSwitchObserver;
184import android.app.Instrumentation;
185import android.app.Notification;
186import android.app.NotificationManager;
187import android.app.PendingIntent;
188import android.app.PictureInPictureArgs;
189import android.app.ProfilerInfo;
190import android.app.RemoteAction;
191import android.app.WaitResult;
192import android.app.admin.DevicePolicyManager;
193import android.app.assist.AssistContent;
194import android.app.assist.AssistStructure;
195import android.app.backup.IBackupManager;
196import android.app.usage.UsageEvents;
197import android.app.usage.UsageStatsManagerInternal;
198import android.appwidget.AppWidgetManager;
199import android.content.ActivityNotFoundException;
200import android.content.BroadcastReceiver;
201import android.content.ClipData;
202import android.content.ComponentCallbacks2;
203import android.content.ComponentName;
204import android.content.ContentProvider;
205import android.content.ContentResolver;
206import android.content.Context;
207import android.content.DialogInterface;
208import android.content.IContentProvider;
209import android.content.IIntentReceiver;
210import android.content.IIntentSender;
211import android.content.Intent;
212import android.content.IntentFilter;
213import android.content.IntentSender;
214import android.content.pm.ActivityInfo;
215import android.content.pm.ApplicationInfo;
216import android.content.pm.ConfigurationInfo;
217import android.content.pm.IPackageDataObserver;
218import android.content.pm.IPackageManager;
219import android.content.pm.InstrumentationInfo;
220import android.content.pm.PackageInfo;
221import android.content.pm.PackageManager;
222import android.content.pm.PackageManager.NameNotFoundException;
223import android.content.pm.PackageManagerInternal;
224import android.content.pm.ParceledListSlice;
225import android.content.pm.PathPermission;
226import android.content.pm.PermissionInfo;
227import android.content.pm.ProviderInfo;
228import android.content.pm.ResolveInfo;
229import android.content.pm.SELinuxUtil;
230import android.content.pm.ServiceInfo;
231import android.content.pm.UserInfo;
232import android.content.res.CompatibilityInfo;
233import android.content.res.Configuration;
234import android.content.res.Resources;
235import android.database.ContentObserver;
236import android.graphics.Bitmap;
237import android.graphics.Point;
238import android.graphics.Rect;
239import android.location.LocationManager;
240import android.media.audiofx.AudioEffect;
241import android.metrics.LogMaker;
242import android.net.Proxy;
243import android.net.ProxyInfo;
244import android.net.Uri;
245import android.os.BatteryStats;
246import android.os.Binder;
247import android.os.Build;
248import android.os.Bundle;
249import android.os.Debug;
250import android.os.DropBoxManager;
251import android.os.Environment;
252import android.os.FactoryTest;
253import android.os.FileObserver;
254import android.os.FileUtils;
255import android.os.Handler;
256import android.os.IBinder;
257import android.os.IDeviceIdentifiersPolicyService;
258import android.os.IPermissionController;
259import android.os.IProcessInfoService;
260import android.os.IProgressListener;
261import android.os.LocaleList;
262import android.os.Looper;
263import android.os.Message;
264import android.os.Parcel;
265import android.os.ParcelFileDescriptor;
266import android.os.PersistableBundle;
267import android.os.PowerManager;
268import android.os.PowerManagerInternal;
269import android.os.Process;
270import android.os.RemoteCallbackList;
271import android.os.RemoteException;
272import android.os.ResultReceiver;
273import android.os.ServiceManager;
274import android.os.ShellCallback;
275import android.os.StrictMode;
276import android.os.SystemClock;
277import android.os.SystemProperties;
278import android.os.Trace;
279import android.os.TransactionTooLargeException;
280import android.os.UpdateLock;
281import android.os.UserHandle;
282import android.os.UserManager;
283import android.os.WorkSource;
284import android.os.storage.IStorageManager;
285import android.os.storage.StorageManager;
286import android.os.storage.StorageManagerInternal;
287import android.provider.Downloads;
288import android.provider.Settings;
289import android.service.voice.IVoiceInteractionSession;
290import android.service.voice.VoiceInteractionManagerInternal;
291import android.service.voice.VoiceInteractionSession;
292import android.telecom.TelecomManager;
293import android.text.TextUtils;
294import android.text.format.DateUtils;
295import android.text.format.Time;
296import android.text.style.SuggestionSpan;
297import android.util.ArrayMap;
298import android.util.ArraySet;
299import android.util.AtomicFile;
300import android.util.BootTimingsTraceLog;
301import android.util.DebugUtils;
302import android.util.DisplayMetrics;
303import android.util.EventLog;
304import android.util.Log;
305import android.util.Pair;
306import android.util.PrintWriterPrinter;
307import android.util.Slog;
308import android.util.SparseArray;
309import android.util.SparseIntArray;
310import android.util.TimeUtils;
311import android.util.Xml;
312import android.view.Gravity;
313import android.view.LayoutInflater;
314import android.view.View;
315import android.view.WindowManager;
316
317import com.google.android.collect.Lists;
318import com.google.android.collect.Maps;
319
320import com.android.internal.R;
321import com.android.internal.annotations.GuardedBy;
322import com.android.internal.app.AssistUtils;
323import com.android.internal.app.DumpHeapActivity;
324import com.android.internal.app.IAppOpsCallback;
325import com.android.internal.app.IAppOpsService;
326import com.android.internal.app.IVoiceInteractor;
327import com.android.internal.app.ProcessMap;
328import com.android.internal.app.SystemUserHomeActivity;
329import com.android.internal.app.procstats.ProcessStats;
330import com.android.internal.logging.MetricsLogger;
331import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
332import com.android.internal.os.BackgroundThread;
333import com.android.internal.os.BatteryStatsImpl;
334import com.android.internal.os.IResultReceiver;
335import com.android.internal.os.ProcessCpuTracker;
336import com.android.internal.os.TransferPipe;
337import com.android.internal.os.Zygote;
338import com.android.internal.policy.IKeyguardDismissCallback;
339import com.android.internal.telephony.TelephonyIntents;
340import com.android.internal.util.ArrayUtils;
341import com.android.internal.util.FastPrintWriter;
342import com.android.internal.util.FastXmlSerializer;
343import com.android.internal.util.MemInfoReader;
344import com.android.internal.util.Preconditions;
345import com.android.server.AppOpsService;
346import com.android.server.AttributeCache;
347import com.android.server.DeviceIdleController;
348import com.android.server.IntentResolver;
349import com.android.server.LocalServices;
350import com.android.server.LockGuard;
351import com.android.server.RescueParty;
352import com.android.server.ServiceThread;
353import com.android.server.SystemConfig;
354import com.android.server.SystemService;
355import com.android.server.SystemServiceManager;
356import com.android.server.Watchdog;
357import com.android.server.am.ActivityStack.ActivityState;
358import com.android.server.firewall.IntentFirewall;
359import com.android.server.pm.Installer;
360import com.android.server.pm.Installer.InstallerException;
361import com.android.server.statusbar.StatusBarManagerInternal;
362import com.android.server.vr.VrManagerInternal;
363import com.android.server.wm.WindowManagerService;
364
365import org.xmlpull.v1.XmlPullParser;
366import org.xmlpull.v1.XmlPullParserException;
367import org.xmlpull.v1.XmlSerializer;
368
369import java.io.File;
370import java.io.FileDescriptor;
371import java.io.FileInputStream;
372import java.io.FileNotFoundException;
373import java.io.FileOutputStream;
374import java.io.IOException;
375import java.io.InputStreamReader;
376import java.io.PrintWriter;
377import java.io.StringWriter;
378import java.lang.ref.WeakReference;
379import java.nio.charset.StandardCharsets;
380import java.util.ArrayList;
381import java.util.Arrays;
382import java.util.Collections;
383import java.util.Comparator;
384import java.util.HashMap;
385import java.util.HashSet;
386import java.util.Iterator;
387import java.util.List;
388import java.util.Locale;
389import java.util.Map;
390import java.util.Objects;
391import java.util.Set;
392import java.util.concurrent.CountDownLatch;
393import java.util.concurrent.atomic.AtomicBoolean;
394import java.util.concurrent.atomic.AtomicLong;
395
396import dalvik.system.VMRuntime;
397
398import libcore.io.IoUtils;
399import libcore.util.EmptyArray;
400
401public class ActivityManagerService extends IActivityManager.Stub
402        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
403
404    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
405    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
406    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
407    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
408    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
409    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
410    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
411    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
412    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
413    private static final String TAG_LRU = TAG + POSTFIX_LRU;
414    private static final String TAG_MU = TAG + POSTFIX_MU;
415    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
416    private static final String TAG_POWER = TAG + POSTFIX_POWER;
417    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
418    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
419    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
420    private static final String TAG_PSS = TAG + POSTFIX_PSS;
421    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
422    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
423    private static final String TAG_STACK = TAG + POSTFIX_STACK;
424    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
425    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
426    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
427    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
428    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
429
430    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
431    // here so that while the job scheduler can depend on AMS, the other way around
432    // need not be the case.
433    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
434
435    /** Control over CPU and battery monitoring */
436    // write battery stats every 30 minutes.
437    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
438    static final boolean MONITOR_CPU_USAGE = true;
439    // don't sample cpu less than every 5 seconds.
440    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
441    // wait possibly forever for next cpu sample.
442    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
443    static final boolean MONITOR_THREAD_CPU_USAGE = false;
444
445    // The flags that are set for all calls we make to the package manager.
446    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
447
448    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
449
450    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
451
452    // Amount of time after a call to stopAppSwitches() during which we will
453    // prevent further untrusted switches from happening.
454    static final long APP_SWITCH_DELAY_TIME = 5*1000;
455
456    // How long we wait for a launched process to attach to the activity manager
457    // before we decide it's never going to come up for real.
458    static final int PROC_START_TIMEOUT = 10*1000;
459    // How long we wait for an attached process to publish its content providers
460    // before we decide it must be hung.
461    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
462
463    // How long we will retain processes hosting content providers in the "last activity"
464    // state before allowing them to drop down to the regular cached LRU list.  This is
465    // to avoid thrashing of provider processes under low memory situations.
466    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
467
468    // How long we wait for a launched process to attach to the activity manager
469    // before we decide it's never going to come up for real, when the process was
470    // started with a wrapper for instrumentation (such as Valgrind) because it
471    // could take much longer than usual.
472    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
473
474    // How long to wait after going idle before forcing apps to GC.
475    static final int GC_TIMEOUT = 5*1000;
476
477    // The minimum amount of time between successive GC requests for a process.
478    static final int GC_MIN_INTERVAL = 60*1000;
479
480    // The minimum amount of time between successive PSS requests for a process.
481    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
482
483    // The minimum amount of time between successive PSS requests for a process
484    // when the request is due to the memory state being lowered.
485    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
486
487    // The rate at which we check for apps using excessive power -- 15 mins.
488    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
489
490    // The minimum sample duration we will allow before deciding we have
491    // enough data on wake locks to start killing things.
492    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
493
494    // The minimum sample duration we will allow before deciding we have
495    // enough data on CPU usage to start killing things.
496    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
497
498    // How long we allow a receiver to run before giving up on it.
499    static final int BROADCAST_FG_TIMEOUT = 10*1000;
500    static final int BROADCAST_BG_TIMEOUT = 60*1000;
501
502    // How long we wait until we timeout on key dispatching.
503    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
504
505    // How long we wait until we timeout on key dispatching during instrumentation.
506    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
507
508    // This is the amount of time an app needs to be running a foreground service before
509    // we will consider it to be doing interaction for usage stats.
510    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
511
512    // Maximum amount of time we will allow to elapse before re-reporting usage stats
513    // interaction with foreground processes.
514    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
515
516    // This is the amount of time we allow an app to settle after it goes into the background,
517    // before we start restricting what it can do.
518    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
519
520    // How long to wait in getAssistContextExtras for the activity and foreground services
521    // to respond with the result.
522    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
523
524    // How long top wait when going through the modern assist (which doesn't need to block
525    // on getting this result before starting to launch its UI).
526    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
527
528    // How long to wait in getAutoFillAssistStructure() for the activity to respond with the result.
529    static final int PENDING_AUTO_FILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
530
531    // Maximum number of persisted Uri grants a package is allowed
532    static final int MAX_PERSISTED_URI_GRANTS = 128;
533
534    static final int MY_PID = Process.myPid();
535
536    static final String[] EMPTY_STRING_ARRAY = new String[0];
537
538    // How many bytes to write into the dropbox log before truncating
539    static final int DROPBOX_MAX_SIZE = 192 * 1024;
540    // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
541    // as one line, but close enough for now.
542    static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
543
544    // Access modes for handleIncomingUser.
545    static final int ALLOW_NON_FULL = 0;
546    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
547    static final int ALLOW_FULL_ONLY = 2;
548
549    // Necessary ApplicationInfo flags to mark an app as persistent
550    private static final int PERSISTENT_MASK =
551            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
552
553    // Intent sent when remote bugreport collection has been completed
554    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
555            "com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED";
556
557    // Used to indicate that an app transition should be animated.
558    static final boolean ANIMATE = true;
559
560    // Determines whether to take full screen screenshots
561    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
562
563    /** All system services */
564    SystemServiceManager mSystemServiceManager;
565    AssistUtils mAssistUtils;
566
567    private Installer mInstaller;
568
569    /** Run all ActivityStacks through this */
570    final ActivityStackSupervisor mStackSupervisor;
571    private final KeyguardController mKeyguardController;
572
573    final ActivityStarter mActivityStarter;
574
575    final TaskChangeNotificationController mTaskChangeNotificationController;
576
577    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
578
579    final ArrayList<ActiveInstrumentation> mActiveInstrumentation = new ArrayList<>();
580
581    public final IntentFirewall mIntentFirewall;
582
583    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
584    // default action automatically.  Important for devices without direct input
585    // devices.
586    private boolean mShowDialogs = true;
587    private boolean mInVrMode = false;
588
589    // Whether we should use SCHED_FIFO for UI and RenderThreads.
590    private boolean mUseFifoUiScheduling = false;
591
592    BroadcastQueue mFgBroadcastQueue;
593    BroadcastQueue mBgBroadcastQueue;
594    // Convenient for easy iteration over the queues. Foreground is first
595    // so that dispatch of foreground broadcasts gets precedence.
596    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
597
598    BroadcastStats mLastBroadcastStats;
599    BroadcastStats mCurBroadcastStats;
600
601    BroadcastQueue broadcastQueueForIntent(Intent intent) {
602        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
603        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
604                "Broadcast intent " + intent + " on "
605                + (isFg ? "foreground" : "background") + " queue");
606        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
607    }
608
609    /**
610     * The last resumed activity. This is identical to the current resumed activity most
611     * of the time but could be different when we're pausing one activity before we resume
612     * another activity.
613     */
614    private ActivityRecord mLastResumedActivity;
615
616    /**
617     * If non-null, we are tracking the time the user spends in the currently focused app.
618     */
619    private AppTimeTracker mCurAppTimeTracker;
620
621    /**
622     * List of intents that were used to start the most recent tasks.
623     */
624    final RecentTasks mRecentTasks;
625
626    /**
627     * For addAppTask: cached of the last activity component that was added.
628     */
629    ComponentName mLastAddedTaskComponent;
630
631    /**
632     * For addAppTask: cached of the last activity uid that was added.
633     */
634    int mLastAddedTaskUid;
635
636    /**
637     * For addAppTask: cached of the last ActivityInfo that was added.
638     */
639    ActivityInfo mLastAddedTaskActivity;
640
641    /**
642     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
643     */
644    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
645
646    /**
647     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
648     */
649    String mDeviceOwnerName;
650
651    final UserController mUserController;
652
653    final AppErrors mAppErrors;
654
655    public boolean canShowErrorDialogs() {
656        return mShowDialogs && !mSleeping && !mShuttingDown
657                && !mKeyguardController.isKeyguardShowing();
658    }
659
660    private static final class PriorityState {
661        // Acts as counter for number of synchronized region that needs to acquire 'this' as a lock
662        // the current thread is currently in. When it drops down to zero, we will no longer boost
663        // the thread's priority.
664        private int regionCounter = 0;
665
666        // The thread's previous priority before boosting.
667        private int prevPriority = Integer.MIN_VALUE;
668    }
669
670    static ThreadLocal<PriorityState> sThreadPriorityState = new ThreadLocal<PriorityState>() {
671        @Override protected PriorityState initialValue() {
672            return new PriorityState();
673        }
674    };
675
676    static void boostPriorityForLockedSection() {
677        int tid = Process.myTid();
678        int prevPriority = Process.getThreadPriority(tid);
679        PriorityState state = sThreadPriorityState.get();
680        if (state.regionCounter == 0 && prevPriority > -2) {
681            state.prevPriority = prevPriority;
682            Process.setThreadPriority(tid, -2);
683        }
684        state.regionCounter++;
685    }
686
687    static void resetPriorityAfterLockedSection() {
688        PriorityState state = sThreadPriorityState.get();
689        state.regionCounter--;
690        if (state.regionCounter == 0 && state.prevPriority > -2) {
691            Process.setThreadPriority(Process.myTid(), state.prevPriority);
692        }
693    }
694
695    public class PendingAssistExtras extends Binder implements Runnable {
696        public final ActivityRecord activity;
697        public final Bundle extras;
698        public final Intent intent;
699        public final String hint;
700        public final IResultReceiver receiver;
701        public final int userHandle;
702        public boolean haveResult = false;
703        public Bundle result = null;
704        public AssistStructure structure = null;
705        public AssistContent content = null;
706        public Bundle receiverExtras;
707
708        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
709                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
710            activity = _activity;
711            extras = _extras;
712            intent = _intent;
713            hint = _hint;
714            receiver = _receiver;
715            receiverExtras = _receiverExtras;
716            userHandle = _userHandle;
717        }
718        @Override
719        public void run() {
720            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
721            synchronized (this) {
722                haveResult = true;
723                notifyAll();
724            }
725            pendingAssistExtrasTimedOut(this);
726        }
727    }
728
729    final ArrayList<PendingAssistExtras> mPendingAssistExtras
730            = new ArrayList<PendingAssistExtras>();
731
732    /**
733     * Process management.
734     */
735    final ProcessList mProcessList = new ProcessList();
736
737    /**
738     * All of the applications we currently have running organized by name.
739     * The keys are strings of the application package name (as
740     * returned by the package manager), and the keys are ApplicationRecord
741     * objects.
742     */
743    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
744
745    /**
746     * Tracking long-term execution of processes to look for abuse and other
747     * bad app behavior.
748     */
749    final ProcessStatsService mProcessStats;
750
751    /**
752     * The currently running isolated processes.
753     */
754    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
755
756    /**
757     * Counter for assigning isolated process uids, to avoid frequently reusing the
758     * same ones.
759     */
760    int mNextIsolatedProcessUid = 0;
761
762    /**
763     * The currently running heavy-weight process, if any.
764     */
765    ProcessRecord mHeavyWeightProcess = null;
766
767    /**
768     * Non-persistent app uid whitelist for background restrictions
769     */
770    int[] mBackgroundUidWhitelist = new int[] {
771            Process.BLUETOOTH_UID
772    };
773
774    /**
775     * Broadcast actions that will always be deliverable to unlaunched/background apps
776     */
777    ArraySet<String> mBackgroundLaunchBroadcasts;
778
779    /**
780     * All of the processes we currently have running organized by pid.
781     * The keys are the pid running the application.
782     *
783     * <p>NOTE: This object is protected by its own lock, NOT the global
784     * activity manager lock!
785     */
786    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
787
788    /**
789     * All of the processes that have been forced to be foreground.  The key
790     * is the pid of the caller who requested it (we hold a death
791     * link on it).
792     */
793    abstract class ForegroundToken implements IBinder.DeathRecipient {
794        int pid;
795        IBinder token;
796    }
797    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
798
799    /**
800     * List of records for processes that someone had tried to start before the
801     * system was ready.  We don't start them at that point, but ensure they
802     * are started by the time booting is complete.
803     */
804    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
805
806    /**
807     * List of persistent applications that are in the process
808     * of being started.
809     */
810    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
811
812    /**
813     * Processes that are being forcibly torn down.
814     */
815    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
816
817    /**
818     * List of running applications, sorted by recent usage.
819     * The first entry in the list is the least recently used.
820     */
821    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
822
823    /**
824     * Where in mLruProcesses that the processes hosting activities start.
825     */
826    int mLruProcessActivityStart = 0;
827
828    /**
829     * Where in mLruProcesses that the processes hosting services start.
830     * This is after (lower index) than mLruProcessesActivityStart.
831     */
832    int mLruProcessServiceStart = 0;
833
834    /**
835     * List of processes that should gc as soon as things are idle.
836     */
837    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
838
839    /**
840     * Processes we want to collect PSS data from.
841     */
842    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
843
844    private boolean mBinderTransactionTrackingEnabled = false;
845
846    /**
847     * Last time we requested PSS data of all processes.
848     */
849    long mLastFullPssTime = SystemClock.uptimeMillis();
850
851    /**
852     * If set, the next time we collect PSS data we should do a full collection
853     * with data from native processes and the kernel.
854     */
855    boolean mFullPssPending = false;
856
857    /**
858     * This is the process holding what we currently consider to be
859     * the "home" activity.
860     */
861    ProcessRecord mHomeProcess;
862
863    /**
864     * This is the process holding the activity the user last visited that
865     * is in a different process from the one they are currently in.
866     */
867    ProcessRecord mPreviousProcess;
868
869    /**
870     * The time at which the previous process was last visible.
871     */
872    long mPreviousProcessVisibleTime;
873
874    /**
875     * Track all uids that have actively running processes.
876     */
877    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
878
879    /**
880     * This is for verifying the UID report flow.
881     */
882    static final boolean VALIDATE_UID_STATES = true;
883    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
884
885    /**
886     * Packages that the user has asked to have run in screen size
887     * compatibility mode instead of filling the screen.
888     */
889    final CompatModePackages mCompatModePackages;
890
891    /**
892     * Set of IntentSenderRecord objects that are currently active.
893     */
894    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
895            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
896
897    /**
898     * Fingerprints (hashCode()) of stack traces that we've
899     * already logged DropBox entries for.  Guarded by itself.  If
900     * something (rogue user app) forces this over
901     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
902     */
903    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
904    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
905
906    /**
907     * Strict Mode background batched logging state.
908     *
909     * The string buffer is guarded by itself, and its lock is also
910     * used to determine if another batched write is already
911     * in-flight.
912     */
913    private final StringBuilder mStrictModeBuffer = new StringBuilder();
914
915    /**
916     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
917     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
918     */
919    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
920
921    /**
922     * Resolver for broadcast intents to registered receivers.
923     * Holds BroadcastFilter (subclass of IntentFilter).
924     */
925    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
926            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
927        @Override
928        protected boolean allowFilterResult(
929                BroadcastFilter filter, List<BroadcastFilter> dest) {
930            IBinder target = filter.receiverList.receiver.asBinder();
931            for (int i = dest.size() - 1; i >= 0; i--) {
932                if (dest.get(i).receiverList.receiver.asBinder() == target) {
933                    return false;
934                }
935            }
936            return true;
937        }
938
939        @Override
940        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
941            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
942                    || userId == filter.owningUserId) {
943                return super.newResult(filter, match, userId);
944            }
945            return null;
946        }
947
948        @Override
949        protected BroadcastFilter[] newArray(int size) {
950            return new BroadcastFilter[size];
951        }
952
953        @Override
954        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
955            return packageName.equals(filter.packageName);
956        }
957    };
958
959    /**
960     * State of all active sticky broadcasts per user.  Keys are the action of the
961     * sticky Intent, values are an ArrayList of all broadcasted intents with
962     * that action (which should usually be one).  The SparseArray is keyed
963     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
964     * for stickies that are sent to all users.
965     */
966    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
967            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
968
969    final ActiveServices mServices;
970
971    final static class Association {
972        final int mSourceUid;
973        final String mSourceProcess;
974        final int mTargetUid;
975        final ComponentName mTargetComponent;
976        final String mTargetProcess;
977
978        int mCount;
979        long mTime;
980
981        int mNesting;
982        long mStartTime;
983
984        // states of the source process when the bind occurred.
985        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
986        long mLastStateUptime;
987        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
988                - ActivityManager.MIN_PROCESS_STATE+1];
989
990        Association(int sourceUid, String sourceProcess, int targetUid,
991                ComponentName targetComponent, String targetProcess) {
992            mSourceUid = sourceUid;
993            mSourceProcess = sourceProcess;
994            mTargetUid = targetUid;
995            mTargetComponent = targetComponent;
996            mTargetProcess = targetProcess;
997        }
998    }
999
1000    /**
1001     * When service association tracking is enabled, this is all of the associations we
1002     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
1003     * -> association data.
1004     */
1005    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
1006            mAssociations = new SparseArray<>();
1007    boolean mTrackingAssociations;
1008
1009    /**
1010     * Backup/restore process management
1011     */
1012    String mBackupAppName = null;
1013    BackupRecord mBackupTarget = null;
1014
1015    final ProviderMap mProviderMap;
1016
1017    /**
1018     * List of content providers who have clients waiting for them.  The
1019     * application is currently being launched and the provider will be
1020     * removed from this list once it is published.
1021     */
1022    final ArrayList<ContentProviderRecord> mLaunchingProviders
1023            = new ArrayList<ContentProviderRecord>();
1024
1025    /**
1026     * File storing persisted {@link #mGrantedUriPermissions}.
1027     */
1028    private final AtomicFile mGrantFile;
1029
1030    /** XML constants used in {@link #mGrantFile} */
1031    private static final String TAG_URI_GRANTS = "uri-grants";
1032    private static final String TAG_URI_GRANT = "uri-grant";
1033    private static final String ATTR_USER_HANDLE = "userHandle";
1034    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1035    private static final String ATTR_TARGET_USER_ID = "targetUserId";
1036    private static final String ATTR_SOURCE_PKG = "sourcePkg";
1037    private static final String ATTR_TARGET_PKG = "targetPkg";
1038    private static final String ATTR_URI = "uri";
1039    private static final String ATTR_MODE_FLAGS = "modeFlags";
1040    private static final String ATTR_CREATED_TIME = "createdTime";
1041    private static final String ATTR_PREFIX = "prefix";
1042
1043    /**
1044     * Global set of specific {@link Uri} permissions that have been granted.
1045     * This optimized lookup structure maps from {@link UriPermission#targetUid}
1046     * to {@link UriPermission#uri} to {@link UriPermission}.
1047     */
1048    @GuardedBy("this")
1049    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1050            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1051
1052    public static class GrantUri {
1053        public final int sourceUserId;
1054        public final Uri uri;
1055        public boolean prefix;
1056
1057        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1058            this.sourceUserId = sourceUserId;
1059            this.uri = uri;
1060            this.prefix = prefix;
1061        }
1062
1063        @Override
1064        public int hashCode() {
1065            int hashCode = 1;
1066            hashCode = 31 * hashCode + sourceUserId;
1067            hashCode = 31 * hashCode + uri.hashCode();
1068            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1069            return hashCode;
1070        }
1071
1072        @Override
1073        public boolean equals(Object o) {
1074            if (o instanceof GrantUri) {
1075                GrantUri other = (GrantUri) o;
1076                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1077                        && prefix == other.prefix;
1078            }
1079            return false;
1080        }
1081
1082        @Override
1083        public String toString() {
1084            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1085            if (prefix) result += " [prefix]";
1086            return result;
1087        }
1088
1089        public String toSafeString() {
1090            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1091            if (prefix) result += " [prefix]";
1092            return result;
1093        }
1094
1095        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1096            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1097                    ContentProvider.getUriWithoutUserId(uri), false);
1098        }
1099    }
1100
1101    CoreSettingsObserver mCoreSettingsObserver;
1102
1103    FontScaleSettingObserver mFontScaleSettingObserver;
1104
1105    private final class FontScaleSettingObserver extends ContentObserver {
1106        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1107
1108        public FontScaleSettingObserver() {
1109            super(mHandler);
1110            ContentResolver resolver = mContext.getContentResolver();
1111            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1112        }
1113
1114        @Override
1115        public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1116            if (mFontScaleUri.equals(uri)) {
1117                updateFontScaleIfNeeded(userId);
1118            }
1119        }
1120    }
1121
1122    /**
1123     * Thread-local storage used to carry caller permissions over through
1124     * indirect content-provider access.
1125     */
1126    private class Identity {
1127        public final IBinder token;
1128        public final int pid;
1129        public final int uid;
1130
1131        Identity(IBinder _token, int _pid, int _uid) {
1132            token = _token;
1133            pid = _pid;
1134            uid = _uid;
1135        }
1136    }
1137
1138    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1139
1140    /**
1141     * All information we have collected about the runtime performance of
1142     * any user id that can impact battery performance.
1143     */
1144    final BatteryStatsService mBatteryStatsService;
1145
1146    /**
1147     * Information about component usage
1148     */
1149    UsageStatsManagerInternal mUsageStatsService;
1150
1151    /**
1152     * Access to DeviceIdleController service.
1153     */
1154    DeviceIdleController.LocalService mLocalDeviceIdleController;
1155
1156    /**
1157     * Set of app ids that are whitelisted for device idle and thus background check.
1158     */
1159    int[] mDeviceIdleWhitelist = new int[0];
1160
1161    /**
1162     * Set of app ids that are temporarily allowed to escape bg check due to high-pri message
1163     */
1164    int[] mDeviceIdleTempWhitelist = new int[0];
1165
1166    /**
1167     * Information about and control over application operations
1168     */
1169    final AppOpsService mAppOpsService;
1170
1171    /** Current sequencing integer of the configuration, for skipping old configurations. */
1172    private int mConfigurationSeq;
1173
1174    /**
1175     * Temp object used when global and/or display override configuration is updated. It is also
1176     * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
1177     * anyone...
1178     */
1179    private Configuration mTempConfig = new Configuration();
1180
1181    private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
1182            new UpdateConfigurationResult();
1183    private static final class UpdateConfigurationResult {
1184        // Configuration changes that were updated.
1185        int changes;
1186        // If the activity was relaunched to match the new configuration.
1187        boolean activityRelaunched;
1188
1189        void reset() {
1190            changes = 0;
1191            activityRelaunched = false;
1192        }
1193    }
1194
1195    boolean mSuppressResizeConfigChanges;
1196
1197    /**
1198     * Hardware-reported OpenGLES version.
1199     */
1200    final int GL_ES_VERSION;
1201
1202    /**
1203     * List of initialization arguments to pass to all processes when binding applications to them.
1204     * For example, references to the commonly used services.
1205     */
1206    HashMap<String, IBinder> mAppBindArgs;
1207    HashMap<String, IBinder> mIsolatedAppBindArgs;
1208
1209    /**
1210     * Temporary to avoid allocations.  Protected by main lock.
1211     */
1212    final StringBuilder mStringBuilder = new StringBuilder(256);
1213
1214    /**
1215     * Used to control how we initialize the service.
1216     */
1217    ComponentName mTopComponent;
1218    String mTopAction = Intent.ACTION_MAIN;
1219    String mTopData;
1220
1221    volatile boolean mProcessesReady = false;
1222    volatile boolean mSystemReady = false;
1223    volatile boolean mOnBattery = false;
1224    volatile int mFactoryTest;
1225
1226    @GuardedBy("this") boolean mBooting = false;
1227    @GuardedBy("this") boolean mCallFinishBooting = false;
1228    @GuardedBy("this") boolean mBootAnimationComplete = false;
1229    @GuardedBy("this") boolean mLaunchWarningShown = false;
1230    @GuardedBy("this") boolean mCheckedForSetup = false;
1231
1232    Context mContext;
1233
1234    /**
1235     * The time at which we will allow normal application switches again,
1236     * after a call to {@link #stopAppSwitches()}.
1237     */
1238    long mAppSwitchesAllowedTime;
1239
1240    /**
1241     * This is set to true after the first switch after mAppSwitchesAllowedTime
1242     * is set; any switches after that will clear the time.
1243     */
1244    boolean mDidAppSwitch;
1245
1246    /**
1247     * Last time (in realtime) at which we checked for power usage.
1248     */
1249    long mLastPowerCheckRealtime;
1250
1251    /**
1252     * Last time (in uptime) at which we checked for power usage.
1253     */
1254    long mLastPowerCheckUptime;
1255
1256    /**
1257     * Set while we are wanting to sleep, to prevent any
1258     * activities from being started/resumed.
1259     *
1260     * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
1261     *
1262     * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
1263     * while in the sleep state until there is a pending transition out of sleep, in which case
1264     * mSleeping is set to false, and remains false while awake.
1265     *
1266     * Whether mSleeping can quickly toggled between true/false without the device actually
1267     * display changing states is undefined.
1268     */
1269    private boolean mSleeping = false;
1270
1271    /**
1272     * The process state used for processes that are running the top activities.
1273     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1274     */
1275    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1276
1277    /**
1278     * Set while we are running a voice interaction.  This overrides
1279     * sleeping while it is active.
1280     */
1281    private IVoiceInteractionSession mRunningVoice;
1282
1283    /**
1284     * For some direct access we need to power manager.
1285     */
1286    PowerManagerInternal mLocalPowerManager;
1287
1288    /**
1289     * We want to hold a wake lock while running a voice interaction session, since
1290     * this may happen with the screen off and we need to keep the CPU running to
1291     * be able to continue to interact with the user.
1292     */
1293    PowerManager.WakeLock mVoiceWakeLock;
1294
1295    /**
1296     * State of external calls telling us if the device is awake or asleep.
1297     */
1298    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1299
1300    /**
1301     * A list of tokens that cause the top activity to be put to sleep.
1302     * They are used by components that may hide and block interaction with underlying
1303     * activities.
1304     */
1305    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1306
1307    /**
1308     * Set if we are shutting down the system, similar to sleeping.
1309     */
1310    boolean mShuttingDown = false;
1311
1312    /**
1313     * Current sequence id for oom_adj computation traversal.
1314     */
1315    int mAdjSeq = 0;
1316
1317    /**
1318     * Current sequence id for process LRU updating.
1319     */
1320    int mLruSeq = 0;
1321
1322    /**
1323     * Keep track of the non-cached/empty process we last found, to help
1324     * determine how to distribute cached/empty processes next time.
1325     */
1326    int mNumNonCachedProcs = 0;
1327
1328    /**
1329     * Keep track of the number of cached hidden procs, to balance oom adj
1330     * distribution between those and empty procs.
1331     */
1332    int mNumCachedHiddenProcs = 0;
1333
1334    /**
1335     * Keep track of the number of service processes we last found, to
1336     * determine on the next iteration which should be B services.
1337     */
1338    int mNumServiceProcs = 0;
1339    int mNewNumAServiceProcs = 0;
1340    int mNewNumServiceProcs = 0;
1341
1342    /**
1343     * Allow the current computed overall memory level of the system to go down?
1344     * This is set to false when we are killing processes for reasons other than
1345     * memory management, so that the now smaller process list will not be taken as
1346     * an indication that memory is tighter.
1347     */
1348    boolean mAllowLowerMemLevel = false;
1349
1350    /**
1351     * The last computed memory level, for holding when we are in a state that
1352     * processes are going away for other reasons.
1353     */
1354    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1355
1356    /**
1357     * The last total number of process we have, to determine if changes actually look
1358     * like a shrinking number of process due to lower RAM.
1359     */
1360    int mLastNumProcesses;
1361
1362    /**
1363     * The uptime of the last time we performed idle maintenance.
1364     */
1365    long mLastIdleTime = SystemClock.uptimeMillis();
1366
1367    /**
1368     * Total time spent with RAM that has been added in the past since the last idle time.
1369     */
1370    long mLowRamTimeSinceLastIdle = 0;
1371
1372    /**
1373     * If RAM is currently low, when that horrible situation started.
1374     */
1375    long mLowRamStartTime = 0;
1376
1377    /**
1378     * For reporting to battery stats the current top application.
1379     */
1380    private String mCurResumedPackage = null;
1381    private int mCurResumedUid = -1;
1382
1383    /**
1384     * For reporting to battery stats the apps currently running foreground
1385     * service.  The ProcessMap is package/uid tuples; each of these contain
1386     * an array of the currently foreground processes.
1387     */
1388    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1389            = new ProcessMap<ArrayList<ProcessRecord>>();
1390
1391    /**
1392     * This is set if we had to do a delayed dexopt of an app before launching
1393     * it, to increase the ANR timeouts in that case.
1394     */
1395    boolean mDidDexOpt;
1396
1397    /**
1398     * Set if the systemServer made a call to enterSafeMode.
1399     */
1400    boolean mSafeMode;
1401
1402    /**
1403     * If true, we are running under a test environment so will sample PSS from processes
1404     * much more rapidly to try to collect better data when the tests are rapidly
1405     * running through apps.
1406     */
1407    boolean mTestPssMode = false;
1408
1409    String mDebugApp = null;
1410    boolean mWaitForDebugger = false;
1411    boolean mDebugTransient = false;
1412    String mOrigDebugApp = null;
1413    boolean mOrigWaitForDebugger = false;
1414    boolean mAlwaysFinishActivities = false;
1415    boolean mForceResizableActivities;
1416    boolean mSupportsMultiWindow;
1417    boolean mSupportsSplitScreenMultiWindow;
1418    boolean mSupportsFreeformWindowManagement;
1419    boolean mSupportsPictureInPicture;
1420    boolean mSupportsLeanbackOnly;
1421    IActivityController mController = null;
1422    boolean mControllerIsAMonkey = false;
1423    String mProfileApp = null;
1424    ProcessRecord mProfileProc = null;
1425    String mProfileFile;
1426    ParcelFileDescriptor mProfileFd;
1427    int mSamplingInterval = 0;
1428    boolean mAutoStopProfiler = false;
1429    boolean mStreamingOutput = false;
1430    int mProfileType = 0;
1431    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1432    String mMemWatchDumpProcName;
1433    String mMemWatchDumpFile;
1434    int mMemWatchDumpPid;
1435    int mMemWatchDumpUid;
1436    String mTrackAllocationApp = null;
1437    String mNativeDebuggingApp = null;
1438
1439    final long[] mTmpLong = new long[2];
1440
1441    private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet();
1442
1443    static final class ProcessChangeItem {
1444        static final int CHANGE_ACTIVITIES = 1<<0;
1445        int changes;
1446        int uid;
1447        int pid;
1448        int processState;
1449        boolean foregroundActivities;
1450    }
1451
1452    static final class UidObserverRegistration {
1453        final int uid;
1454        final String pkg;
1455        final int which;
1456        final int cutpoint;
1457
1458        final SparseIntArray lastProcStates;
1459
1460        UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) {
1461            uid = _uid;
1462            pkg = _pkg;
1463            which = _which;
1464            cutpoint = _cutpoint;
1465            if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
1466                lastProcStates = new SparseIntArray();
1467            } else {
1468                lastProcStates = null;
1469            }
1470        }
1471    }
1472
1473    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1474    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1475
1476    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1477    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1478
1479    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1480    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1481
1482    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1483    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1484
1485    /**
1486     * Runtime CPU use collection thread.  This object's lock is used to
1487     * perform synchronization with the thread (notifying it to run).
1488     */
1489    final Thread mProcessCpuThread;
1490
1491    /**
1492     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1493     * Must acquire this object's lock when accessing it.
1494     * NOTE: this lock will be held while doing long operations (trawling
1495     * through all processes in /proc), so it should never be acquired by
1496     * any critical paths such as when holding the main activity manager lock.
1497     */
1498    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1499            MONITOR_THREAD_CPU_USAGE);
1500    final AtomicLong mLastCpuTime = new AtomicLong(0);
1501    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1502    final CountDownLatch mProcessCpuInitLatch = new CountDownLatch(1);
1503
1504    long mLastWriteTime = 0;
1505
1506    /**
1507     * Used to retain an update lock when the foreground activity is in
1508     * immersive mode.
1509     */
1510    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1511
1512    /**
1513     * Set to true after the system has finished booting.
1514     */
1515    boolean mBooted = false;
1516
1517    WindowManagerService mWindowManager;
1518    final ActivityThread mSystemThread;
1519
1520    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1521        final ProcessRecord mApp;
1522        final int mPid;
1523        final IApplicationThread mAppThread;
1524
1525        AppDeathRecipient(ProcessRecord app, int pid,
1526                IApplicationThread thread) {
1527            if (DEBUG_ALL) Slog.v(
1528                TAG, "New death recipient " + this
1529                + " for thread " + thread.asBinder());
1530            mApp = app;
1531            mPid = pid;
1532            mAppThread = thread;
1533        }
1534
1535        @Override
1536        public void binderDied() {
1537            if (DEBUG_ALL) Slog.v(
1538                TAG, "Death received in " + this
1539                + " for thread " + mAppThread.asBinder());
1540            synchronized(ActivityManagerService.this) {
1541                appDiedLocked(mApp, mPid, mAppThread, true);
1542            }
1543        }
1544    }
1545
1546    static final int SHOW_ERROR_UI_MSG = 1;
1547    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1548    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1549    static final int UPDATE_CONFIGURATION_MSG = 4;
1550    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1551    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1552    static final int SERVICE_TIMEOUT_MSG = 12;
1553    static final int UPDATE_TIME_ZONE = 13;
1554    static final int SHOW_UID_ERROR_UI_MSG = 14;
1555    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1556    static final int PROC_START_TIMEOUT_MSG = 20;
1557    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1558    static final int KILL_APPLICATION_MSG = 22;
1559    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1560    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1561    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1562    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1563    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1564    static final int CLEAR_DNS_CACHE_MSG = 28;
1565    static final int UPDATE_HTTP_PROXY_MSG = 29;
1566    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1567    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1568    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1569    static final int REPORT_MEM_USAGE_MSG = 33;
1570    static final int REPORT_USER_SWITCH_MSG = 34;
1571    static final int CONTINUE_USER_SWITCH_MSG = 35;
1572    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1573    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1574    static final int PERSIST_URI_GRANTS_MSG = 38;
1575    static final int REQUEST_ALL_PSS_MSG = 39;
1576    static final int START_PROFILES_MSG = 40;
1577    static final int UPDATE_TIME_PREFERENCE_MSG = 41;
1578    static final int SYSTEM_USER_START_MSG = 42;
1579    static final int SYSTEM_USER_CURRENT_MSG = 43;
1580    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1581    static final int FINISH_BOOTING_MSG = 45;
1582    static final int START_USER_SWITCH_UI_MSG = 46;
1583    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1584    static final int DISMISS_DIALOG_UI_MSG = 48;
1585    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
1586    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
1587    static final int DELETE_DUMPHEAP_MSG = 51;
1588    static final int FOREGROUND_PROFILE_CHANGED_MSG = 52;
1589    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
1590    static final int REPORT_TIME_TRACKER_MSG = 54;
1591    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 55;
1592    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
1593    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
1594    static final int IDLE_UIDS_MSG = 58;
1595    static final int SYSTEM_USER_UNLOCK_MSG = 59;
1596    static final int LOG_STACK_STATE = 60;
1597    static final int VR_MODE_CHANGE_MSG = 61;
1598    static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 62;
1599    static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
1600    static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 64;
1601    static final int NOTIFY_VR_SLEEPING_MSG = 65;
1602    static final int START_USER_SWITCH_FG_MSG = 712;
1603
1604    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1605    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1606    static final int FIRST_COMPAT_MODE_MSG = 300;
1607    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1608
1609    static ServiceThread sKillThread = null;
1610    static KillHandler sKillHandler = null;
1611
1612    CompatModeDialog mCompatModeDialog;
1613    UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1614    long mLastMemUsageReportTime = 0;
1615
1616    /**
1617     * Flag whether the current user is a "monkey", i.e. whether
1618     * the UI is driven by a UI automation tool.
1619     */
1620    private boolean mUserIsMonkey;
1621
1622    /** Flag whether the device has a Recents UI */
1623    boolean mHasRecents;
1624
1625    /** The dimensions of the thumbnails in the Recents UI. */
1626    int mThumbnailWidth;
1627    int mThumbnailHeight;
1628    float mFullscreenThumbnailScale;
1629
1630    final ServiceThread mHandlerThread;
1631    final MainHandler mHandler;
1632    final UiHandler mUiHandler;
1633
1634    final ActivityManagerConstants mConstants;
1635
1636    PackageManagerInternal mPackageManagerInt;
1637
1638    // VoiceInteraction session ID that changes for each new request except when
1639    // being called for multiwindow assist in a single session.
1640    private int mViSessionId = 1000;
1641
1642    final boolean mPermissionReviewRequired;
1643
1644    /**
1645     * Current global configuration information. Contains general settings for the entire system,
1646     * also corresponds to the merged configuration of the default display.
1647     */
1648    Configuration getGlobalConfiguration() {
1649        return mStackSupervisor.getConfiguration();
1650    }
1651
1652    final class KillHandler extends Handler {
1653        static final int KILL_PROCESS_GROUP_MSG = 4000;
1654
1655        public KillHandler(Looper looper) {
1656            super(looper, null, true);
1657        }
1658
1659        @Override
1660        public void handleMessage(Message msg) {
1661            switch (msg.what) {
1662                case KILL_PROCESS_GROUP_MSG:
1663                {
1664                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1665                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1666                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1667                }
1668                break;
1669
1670                default:
1671                    super.handleMessage(msg);
1672            }
1673        }
1674    }
1675
1676    final class UiHandler extends Handler {
1677        public UiHandler() {
1678            super(com.android.server.UiThread.get().getLooper(), null, true);
1679        }
1680
1681        @Override
1682        public void handleMessage(Message msg) {
1683            switch (msg.what) {
1684            case SHOW_ERROR_UI_MSG: {
1685                mAppErrors.handleShowAppErrorUi(msg);
1686                ensureBootCompleted();
1687            } break;
1688            case SHOW_NOT_RESPONDING_UI_MSG: {
1689                mAppErrors.handleShowAnrUi(msg);
1690                ensureBootCompleted();
1691            } break;
1692            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1693                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1694                synchronized (ActivityManagerService.this) {
1695                    ProcessRecord proc = (ProcessRecord) data.get("app");
1696                    if (proc == null) {
1697                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1698                        break;
1699                    }
1700                    if (proc.crashDialog != null) {
1701                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1702                        return;
1703                    }
1704                    AppErrorResult res = (AppErrorResult) data.get("result");
1705                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1706                        Dialog d = new StrictModeViolationDialog(mContext,
1707                                ActivityManagerService.this, res, proc);
1708                        d.show();
1709                        proc.crashDialog = d;
1710                    } else {
1711                        // The device is asleep, so just pretend that the user
1712                        // saw a crash dialog and hit "force quit".
1713                        res.set(0);
1714                    }
1715                }
1716                ensureBootCompleted();
1717            } break;
1718            case SHOW_FACTORY_ERROR_UI_MSG: {
1719                Dialog d = new FactoryErrorDialog(
1720                    mContext, msg.getData().getCharSequence("msg"));
1721                d.show();
1722                ensureBootCompleted();
1723            } break;
1724            case WAIT_FOR_DEBUGGER_UI_MSG: {
1725                synchronized (ActivityManagerService.this) {
1726                    ProcessRecord app = (ProcessRecord)msg.obj;
1727                    if (msg.arg1 != 0) {
1728                        if (!app.waitedForDebugger) {
1729                            Dialog d = new AppWaitingForDebuggerDialog(
1730                                    ActivityManagerService.this,
1731                                    mContext, app);
1732                            app.waitDialog = d;
1733                            app.waitedForDebugger = true;
1734                            d.show();
1735                        }
1736                    } else {
1737                        if (app.waitDialog != null) {
1738                            app.waitDialog.dismiss();
1739                            app.waitDialog = null;
1740                        }
1741                    }
1742                }
1743            } break;
1744            case SHOW_UID_ERROR_UI_MSG: {
1745                if (mShowDialogs) {
1746                    AlertDialog d = new BaseErrorDialog(mContext);
1747                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1748                    d.setCancelable(false);
1749                    d.setTitle(mContext.getText(R.string.android_system_label));
1750                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1751                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1752                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1753                    d.show();
1754                }
1755            } break;
1756            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1757                if (mShowDialogs) {
1758                    AlertDialog d = new BaseErrorDialog(mContext);
1759                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1760                    d.setCancelable(false);
1761                    d.setTitle(mContext.getText(R.string.android_system_label));
1762                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1763                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1764                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1765                    d.show();
1766                }
1767            } break;
1768            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1769                synchronized (ActivityManagerService.this) {
1770                    ActivityRecord ar = (ActivityRecord) msg.obj;
1771                    if (mCompatModeDialog != null) {
1772                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1773                                ar.info.applicationInfo.packageName)) {
1774                            return;
1775                        }
1776                        mCompatModeDialog.dismiss();
1777                        mCompatModeDialog = null;
1778                    }
1779                    if (ar != null && false) {
1780                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1781                                ar.packageName)) {
1782                            int mode = mCompatModePackages.computeCompatModeLocked(
1783                                    ar.info.applicationInfo);
1784                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1785                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1786                                mCompatModeDialog = new CompatModeDialog(
1787                                        ActivityManagerService.this, mContext,
1788                                        ar.info.applicationInfo);
1789                                mCompatModeDialog.show();
1790                            }
1791                        }
1792                    }
1793                }
1794                break;
1795            }
1796            case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1797                synchronized (ActivityManagerService.this) {
1798                    final ActivityRecord ar = (ActivityRecord) msg.obj;
1799                    if (mUnsupportedDisplaySizeDialog != null) {
1800                        mUnsupportedDisplaySizeDialog.dismiss();
1801                        mUnsupportedDisplaySizeDialog = null;
1802                    }
1803                    if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1804                            ar.packageName)) {
1805                        // TODO(multi-display): Show dialog on appropriate display.
1806                        mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1807                                ActivityManagerService.this, mContext, ar.info.applicationInfo);
1808                        mUnsupportedDisplaySizeDialog.show();
1809                    }
1810                }
1811                break;
1812            }
1813            case START_USER_SWITCH_UI_MSG: {
1814                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1815                break;
1816            }
1817            case DISMISS_DIALOG_UI_MSG: {
1818                final Dialog d = (Dialog) msg.obj;
1819                d.dismiss();
1820                break;
1821            }
1822            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1823                dispatchProcessesChanged();
1824                break;
1825            }
1826            case DISPATCH_PROCESS_DIED_UI_MSG: {
1827                final int pid = msg.arg1;
1828                final int uid = msg.arg2;
1829                dispatchProcessDied(pid, uid);
1830                break;
1831            }
1832            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1833                dispatchUidsChanged();
1834            } break;
1835            }
1836        }
1837    }
1838
1839    final class MainHandler extends Handler {
1840        public MainHandler(Looper looper) {
1841            super(looper, null, true);
1842        }
1843
1844        @Override
1845        public void handleMessage(Message msg) {
1846            switch (msg.what) {
1847            case UPDATE_CONFIGURATION_MSG: {
1848                final ContentResolver resolver = mContext.getContentResolver();
1849                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1850                        msg.arg1);
1851            } break;
1852            case GC_BACKGROUND_PROCESSES_MSG: {
1853                synchronized (ActivityManagerService.this) {
1854                    performAppGcsIfAppropriateLocked();
1855                }
1856            } break;
1857            case SERVICE_TIMEOUT_MSG: {
1858                if (mDidDexOpt) {
1859                    mDidDexOpt = false;
1860                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1861                    nmsg.obj = msg.obj;
1862                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1863                    return;
1864                }
1865                mServices.serviceTimeout((ProcessRecord)msg.obj);
1866            } break;
1867            case UPDATE_TIME_ZONE: {
1868                synchronized (ActivityManagerService.this) {
1869                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1870                        ProcessRecord r = mLruProcesses.get(i);
1871                        if (r.thread != null) {
1872                            try {
1873                                r.thread.updateTimeZone();
1874                            } catch (RemoteException ex) {
1875                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1876                            }
1877                        }
1878                    }
1879                }
1880            } break;
1881            case CLEAR_DNS_CACHE_MSG: {
1882                synchronized (ActivityManagerService.this) {
1883                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1884                        ProcessRecord r = mLruProcesses.get(i);
1885                        if (r.thread != null) {
1886                            try {
1887                                r.thread.clearDnsCache();
1888                            } catch (RemoteException ex) {
1889                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1890                            }
1891                        }
1892                    }
1893                }
1894            } break;
1895            case UPDATE_HTTP_PROXY_MSG: {
1896                ProxyInfo proxy = (ProxyInfo)msg.obj;
1897                String host = "";
1898                String port = "";
1899                String exclList = "";
1900                Uri pacFileUrl = Uri.EMPTY;
1901                if (proxy != null) {
1902                    host = proxy.getHost();
1903                    port = Integer.toString(proxy.getPort());
1904                    exclList = proxy.getExclusionListAsString();
1905                    pacFileUrl = proxy.getPacFileUrl();
1906                }
1907                synchronized (ActivityManagerService.this) {
1908                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1909                        ProcessRecord r = mLruProcesses.get(i);
1910                        if (r.thread != null) {
1911                            try {
1912                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1913                            } catch (RemoteException ex) {
1914                                Slog.w(TAG, "Failed to update http proxy for: " +
1915                                        r.info.processName);
1916                            }
1917                        }
1918                    }
1919                }
1920            } break;
1921            case PROC_START_TIMEOUT_MSG: {
1922                if (mDidDexOpt) {
1923                    mDidDexOpt = false;
1924                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1925                    nmsg.obj = msg.obj;
1926                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1927                    return;
1928                }
1929                ProcessRecord app = (ProcessRecord)msg.obj;
1930                synchronized (ActivityManagerService.this) {
1931                    processStartTimedOutLocked(app);
1932                }
1933            } break;
1934            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1935                ProcessRecord app = (ProcessRecord)msg.obj;
1936                synchronized (ActivityManagerService.this) {
1937                    processContentProviderPublishTimedOutLocked(app);
1938                }
1939            } break;
1940            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1941                synchronized (ActivityManagerService.this) {
1942                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1943                }
1944            } break;
1945            case KILL_APPLICATION_MSG: {
1946                synchronized (ActivityManagerService.this) {
1947                    final int appId = msg.arg1;
1948                    final int userId = msg.arg2;
1949                    Bundle bundle = (Bundle)msg.obj;
1950                    String pkg = bundle.getString("pkg");
1951                    String reason = bundle.getString("reason");
1952                    forceStopPackageLocked(pkg, appId, false, false, true, false,
1953                            false, userId, reason);
1954                }
1955            } break;
1956            case FINALIZE_PENDING_INTENT_MSG: {
1957                ((PendingIntentRecord)msg.obj).completeFinalize();
1958            } break;
1959            case POST_HEAVY_NOTIFICATION_MSG: {
1960                INotificationManager inm = NotificationManager.getService();
1961                if (inm == null) {
1962                    return;
1963                }
1964
1965                ActivityRecord root = (ActivityRecord)msg.obj;
1966                ProcessRecord process = root.app;
1967                if (process == null) {
1968                    return;
1969                }
1970
1971                try {
1972                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1973                    String text = mContext.getString(R.string.heavy_weight_notification,
1974                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1975                    Notification notification = new Notification.Builder(context)
1976                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1977                            .setWhen(0)
1978                            .setOngoing(true)
1979                            .setTicker(text)
1980                            .setColor(mContext.getColor(
1981                                    com.android.internal.R.color.system_notification_accent_color))
1982                            .setContentTitle(text)
1983                            .setContentText(
1984                                    mContext.getText(R.string.heavy_weight_notification_detail))
1985                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1986                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1987                                    new UserHandle(root.userId)))
1988                            .build();
1989                    try {
1990                        int[] outId = new int[1];
1991                        inm.enqueueNotificationWithTag("android", "android", null,
1992                                R.string.heavy_weight_notification,
1993                                notification, outId, root.userId);
1994                    } catch (RuntimeException e) {
1995                        Slog.w(ActivityManagerService.TAG,
1996                                "Error showing notification for heavy-weight app", e);
1997                    } catch (RemoteException e) {
1998                    }
1999                } catch (NameNotFoundException e) {
2000                    Slog.w(TAG, "Unable to create context for heavy notification", e);
2001                }
2002            } break;
2003            case CANCEL_HEAVY_NOTIFICATION_MSG: {
2004                INotificationManager inm = NotificationManager.getService();
2005                if (inm == null) {
2006                    return;
2007                }
2008                try {
2009                    inm.cancelNotificationWithTag("android", null,
2010                            R.string.heavy_weight_notification,  msg.arg1);
2011                } catch (RuntimeException e) {
2012                    Slog.w(ActivityManagerService.TAG,
2013                            "Error canceling notification for service", e);
2014                } catch (RemoteException e) {
2015                }
2016            } break;
2017            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
2018                synchronized (ActivityManagerService.this) {
2019                    checkExcessivePowerUsageLocked(true);
2020                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
2021                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
2022                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
2023                }
2024            } break;
2025            case REPORT_MEM_USAGE_MSG: {
2026                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
2027                Thread thread = new Thread() {
2028                    @Override public void run() {
2029                        reportMemUsage(memInfos);
2030                    }
2031                };
2032                thread.start();
2033                break;
2034            }
2035            case START_USER_SWITCH_FG_MSG: {
2036                mUserController.startUserInForeground(msg.arg1);
2037                break;
2038            }
2039            case REPORT_USER_SWITCH_MSG: {
2040                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2041                break;
2042            }
2043            case CONTINUE_USER_SWITCH_MSG: {
2044                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2045                break;
2046            }
2047            case USER_SWITCH_TIMEOUT_MSG: {
2048                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2049                break;
2050            }
2051            case IMMERSIVE_MODE_LOCK_MSG: {
2052                final boolean nextState = (msg.arg1 != 0);
2053                if (mUpdateLock.isHeld() != nextState) {
2054                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
2055                            "Applying new update lock state '" + nextState
2056                            + "' for " + (ActivityRecord)msg.obj);
2057                    if (nextState) {
2058                        mUpdateLock.acquire();
2059                    } else {
2060                        mUpdateLock.release();
2061                    }
2062                }
2063                break;
2064            }
2065            case PERSIST_URI_GRANTS_MSG: {
2066                writeGrantedUriPermissions();
2067                break;
2068            }
2069            case REQUEST_ALL_PSS_MSG: {
2070                synchronized (ActivityManagerService.this) {
2071                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
2072                }
2073                break;
2074            }
2075            case START_PROFILES_MSG: {
2076                synchronized (ActivityManagerService.this) {
2077                    mUserController.startProfilesLocked();
2078                }
2079                break;
2080            }
2081            case UPDATE_TIME_PREFERENCE_MSG: {
2082                // The user's time format preference might have changed.
2083                // For convenience we re-use the Intent extra values.
2084                synchronized (ActivityManagerService.this) {
2085                    for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2086                        ProcessRecord r = mLruProcesses.get(i);
2087                        if (r.thread != null) {
2088                            try {
2089                                r.thread.updateTimePrefs(msg.arg1);
2090                            } catch (RemoteException ex) {
2091                                Slog.w(TAG, "Failed to update preferences for: "
2092                                        + r.info.processName);
2093                            }
2094                        }
2095                    }
2096                }
2097                break;
2098            }
2099            case SYSTEM_USER_START_MSG: {
2100                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2101                        Integer.toString(msg.arg1), msg.arg1);
2102                mSystemServiceManager.startUser(msg.arg1);
2103                break;
2104            }
2105            case SYSTEM_USER_UNLOCK_MSG: {
2106                final int userId = msg.arg1;
2107                mSystemServiceManager.unlockUser(userId);
2108                synchronized (ActivityManagerService.this) {
2109                    mRecentTasks.loadUserRecentsLocked(userId);
2110                }
2111                if (userId == UserHandle.USER_SYSTEM) {
2112                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2113                }
2114                installEncryptionUnawareProviders(userId);
2115                mUserController.finishUserUnlocked((UserState) msg.obj);
2116                break;
2117            }
2118            case SYSTEM_USER_CURRENT_MSG: {
2119                mBatteryStatsService.noteEvent(
2120                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2121                        Integer.toString(msg.arg2), msg.arg2);
2122                mBatteryStatsService.noteEvent(
2123                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2124                        Integer.toString(msg.arg1), msg.arg1);
2125                mSystemServiceManager.switchUser(msg.arg1);
2126                break;
2127            }
2128            case ENTER_ANIMATION_COMPLETE_MSG: {
2129                synchronized (ActivityManagerService.this) {
2130                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2131                    if (r != null && r.app != null && r.app.thread != null) {
2132                        try {
2133                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2134                        } catch (RemoteException e) {
2135                        }
2136                    }
2137                }
2138                break;
2139            }
2140            case FINISH_BOOTING_MSG: {
2141                if (msg.arg1 != 0) {
2142                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2143                    finishBooting();
2144                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2145                }
2146                if (msg.arg2 != 0) {
2147                    enableScreenAfterBoot();
2148                }
2149                break;
2150            }
2151            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2152                try {
2153                    Locale l = (Locale) msg.obj;
2154                    IBinder service = ServiceManager.getService("mount");
2155                    IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
2156                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2157                    storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2158                } catch (RemoteException e) {
2159                    Log.e(TAG, "Error storing locale for decryption UI", e);
2160                }
2161                break;
2162            }
2163            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2164                final int uid = msg.arg1;
2165                final byte[] firstPacket = (byte[]) msg.obj;
2166
2167                synchronized (mPidsSelfLocked) {
2168                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2169                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2170                        if (p.uid == uid) {
2171                            try {
2172                                p.thread.notifyCleartextNetwork(firstPacket);
2173                            } catch (RemoteException ignored) {
2174                            }
2175                        }
2176                    }
2177                }
2178                break;
2179            }
2180            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2181                final String procName;
2182                final int uid;
2183                final long memLimit;
2184                final String reportPackage;
2185                synchronized (ActivityManagerService.this) {
2186                    procName = mMemWatchDumpProcName;
2187                    uid = mMemWatchDumpUid;
2188                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2189                    if (val == null) {
2190                        val = mMemWatchProcesses.get(procName, 0);
2191                    }
2192                    if (val != null) {
2193                        memLimit = val.first;
2194                        reportPackage = val.second;
2195                    } else {
2196                        memLimit = 0;
2197                        reportPackage = null;
2198                    }
2199                }
2200                if (procName == null) {
2201                    return;
2202                }
2203
2204                if (DEBUG_PSS) Slog.d(TAG_PSS,
2205                        "Showing dump heap notification from " + procName + "/" + uid);
2206
2207                INotificationManager inm = NotificationManager.getService();
2208                if (inm == null) {
2209                    return;
2210                }
2211
2212                String text = mContext.getString(R.string.dump_heap_notification, procName);
2213
2214
2215                Intent deleteIntent = new Intent();
2216                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2217                Intent intent = new Intent();
2218                intent.setClassName("android", DumpHeapActivity.class.getName());
2219                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2220                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2221                if (reportPackage != null) {
2222                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2223                }
2224                int userId = UserHandle.getUserId(uid);
2225                Notification notification = new Notification.Builder(mContext)
2226                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2227                        .setWhen(0)
2228                        .setOngoing(true)
2229                        .setAutoCancel(true)
2230                        .setTicker(text)
2231                        .setColor(mContext.getColor(
2232                                com.android.internal.R.color.system_notification_accent_color))
2233                        .setContentTitle(text)
2234                        .setContentText(
2235                                mContext.getText(R.string.dump_heap_notification_detail))
2236                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2237                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2238                                new UserHandle(userId)))
2239                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2240                                deleteIntent, 0, UserHandle.SYSTEM))
2241                        .build();
2242
2243                try {
2244                    int[] outId = new int[1];
2245                    inm.enqueueNotificationWithTag("android", "android", null,
2246                            R.string.dump_heap_notification,
2247                            notification, outId, userId);
2248                } catch (RuntimeException e) {
2249                    Slog.w(ActivityManagerService.TAG,
2250                            "Error showing notification for dump heap", e);
2251                } catch (RemoteException e) {
2252                }
2253            } break;
2254            case DELETE_DUMPHEAP_MSG: {
2255                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2256                        DumpHeapActivity.JAVA_URI,
2257                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2258                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2259                        UserHandle.myUserId());
2260                synchronized (ActivityManagerService.this) {
2261                    mMemWatchDumpFile = null;
2262                    mMemWatchDumpProcName = null;
2263                    mMemWatchDumpPid = -1;
2264                    mMemWatchDumpUid = -1;
2265                }
2266            } break;
2267            case FOREGROUND_PROFILE_CHANGED_MSG: {
2268                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2269            } break;
2270            case REPORT_TIME_TRACKER_MSG: {
2271                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2272                tracker.deliverResult(mContext);
2273            } break;
2274            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2275                mUserController.dispatchUserSwitchComplete(msg.arg1);
2276            } break;
2277            case REPORT_LOCKED_BOOT_COMPLETE_MSG: {
2278                mUserController.dispatchLockedBootComplete(msg.arg1);
2279            } break;
2280            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2281                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2282                try {
2283                    connection.shutdown();
2284                } catch (RemoteException e) {
2285                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2286                }
2287                // Only a UiAutomation can set this flag and now that
2288                // it is finished we make sure it is reset to its default.
2289                mUserIsMonkey = false;
2290            } break;
2291            case IDLE_UIDS_MSG: {
2292                idleUids();
2293            } break;
2294            case VR_MODE_CHANGE_MSG: {
2295                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2296                if (vrService == null) {
2297                    break;
2298                }
2299                final ActivityRecord r = (ActivityRecord) msg.obj;
2300                boolean vrMode;
2301                ComponentName requestedPackage;
2302                ComponentName callingPackage;
2303                int userId;
2304                synchronized (ActivityManagerService.this) {
2305                    vrMode = r.requestedVrComponent != null;
2306                    requestedPackage = r.requestedVrComponent;
2307                    userId = r.userId;
2308                    callingPackage = r.info.getComponentName();
2309                    if (mInVrMode != vrMode) {
2310                        mInVrMode = vrMode;
2311                        mShowDialogs = shouldShowDialogs(getGlobalConfiguration(), mInVrMode);
2312                        if (r.app != null) {
2313                            ProcessRecord proc = r.app;
2314                            if (proc.vrThreadTid > 0) {
2315                                if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
2316                                    try {
2317                                        if (mInVrMode == true) {
2318                                            Process.setThreadScheduler(proc.vrThreadTid,
2319                                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
2320                                        } else {
2321                                            Process.setThreadScheduler(proc.vrThreadTid,
2322                                                Process.SCHED_OTHER, 0);
2323                                        }
2324                                    } catch (IllegalArgumentException e) {
2325                                        Slog.w(TAG, "Failed to set scheduling policy, thread does"
2326                                                + " not exist:\n" + e);
2327                                    }
2328                                }
2329                            }
2330                        }
2331                    }
2332                }
2333                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2334            } break;
2335            case NOTIFY_VR_SLEEPING_MSG: {
2336                notifyVrManagerOfSleepState(msg.arg1 != 0);
2337            } break;
2338            case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
2339                synchronized (ActivityManagerService.this) {
2340                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2341                        ProcessRecord r = mLruProcesses.get(i);
2342                        if (r.thread != null) {
2343                            try {
2344                                r.thread.handleTrustStorageUpdate();
2345                            } catch (RemoteException ex) {
2346                                Slog.w(TAG, "Failed to handle trust storage update for: " +
2347                                        r.info.processName);
2348                            }
2349                        }
2350                    }
2351                }
2352            } break;
2353            }
2354        }
2355    };
2356
2357    static final int COLLECT_PSS_BG_MSG = 1;
2358
2359    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2360        @Override
2361        public void handleMessage(Message msg) {
2362            switch (msg.what) {
2363            case COLLECT_PSS_BG_MSG: {
2364                long start = SystemClock.uptimeMillis();
2365                MemInfoReader memInfo = null;
2366                synchronized (ActivityManagerService.this) {
2367                    if (mFullPssPending) {
2368                        mFullPssPending = false;
2369                        memInfo = new MemInfoReader();
2370                    }
2371                }
2372                if (memInfo != null) {
2373                    updateCpuStatsNow();
2374                    long nativeTotalPss = 0;
2375                    final List<ProcessCpuTracker.Stats> stats;
2376                    synchronized (mProcessCpuTracker) {
2377                        stats = mProcessCpuTracker.getStats( (st)-> {
2378                            return st.vsize > 0 && st.uid < Process.FIRST_APPLICATION_UID;
2379                        });
2380                    }
2381                    final int N = stats.size();
2382                    for (int j = 0; j < N; j++) {
2383                        synchronized (mPidsSelfLocked) {
2384                            if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2385                                // This is one of our own processes; skip it.
2386                                continue;
2387                            }
2388                        }
2389                        nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2390                    }
2391                    memInfo.readMemInfo();
2392                    synchronized (ActivityManagerService.this) {
2393                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2394                                + (SystemClock.uptimeMillis()-start) + "ms");
2395                        final long cachedKb = memInfo.getCachedSizeKb();
2396                        final long freeKb = memInfo.getFreeSizeKb();
2397                        final long zramKb = memInfo.getZramTotalSizeKb();
2398                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2399                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2400                                kernelKb*1024, nativeTotalPss*1024);
2401                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2402                                nativeTotalPss);
2403                    }
2404                }
2405
2406                int num = 0;
2407                long[] tmp = new long[2];
2408                do {
2409                    ProcessRecord proc;
2410                    int procState;
2411                    int pid;
2412                    long lastPssTime;
2413                    synchronized (ActivityManagerService.this) {
2414                        if (mPendingPssProcesses.size() <= 0) {
2415                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2416                                    "Collected PSS of " + num + " processes in "
2417                                    + (SystemClock.uptimeMillis() - start) + "ms");
2418                            mPendingPssProcesses.clear();
2419                            return;
2420                        }
2421                        proc = mPendingPssProcesses.remove(0);
2422                        procState = proc.pssProcState;
2423                        lastPssTime = proc.lastPssTime;
2424                        if (proc.thread != null && procState == proc.setProcState
2425                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2426                                        < SystemClock.uptimeMillis()) {
2427                            pid = proc.pid;
2428                        } else {
2429                            proc = null;
2430                            pid = 0;
2431                        }
2432                    }
2433                    if (proc != null) {
2434                        long pss = Debug.getPss(pid, tmp, null);
2435                        synchronized (ActivityManagerService.this) {
2436                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2437                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2438                                num++;
2439                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2440                                        SystemClock.uptimeMillis());
2441                            }
2442                        }
2443                    }
2444                } while (true);
2445            }
2446            }
2447        }
2448    };
2449
2450    public void setSystemProcess() {
2451        try {
2452            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2453            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2454            ServiceManager.addService("meminfo", new MemBinder(this));
2455            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2456            ServiceManager.addService("dbinfo", new DbBinder(this));
2457            if (MONITOR_CPU_USAGE) {
2458                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2459            }
2460            ServiceManager.addService("permission", new PermissionController(this));
2461            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2462
2463            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2464                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2465            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2466
2467            synchronized (this) {
2468                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2469                app.persistent = true;
2470                app.pid = MY_PID;
2471                app.maxAdj = ProcessList.SYSTEM_ADJ;
2472                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2473                synchronized (mPidsSelfLocked) {
2474                    mPidsSelfLocked.put(app.pid, app);
2475                }
2476                updateLruProcessLocked(app, false, null);
2477                updateOomAdjLocked();
2478            }
2479        } catch (PackageManager.NameNotFoundException e) {
2480            throw new RuntimeException(
2481                    "Unable to find android system package", e);
2482        }
2483    }
2484
2485    public void setWindowManager(WindowManagerService wm) {
2486        mWindowManager = wm;
2487        mStackSupervisor.setWindowManager(wm);
2488        mActivityStarter.setWindowManager(wm);
2489    }
2490
2491    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2492        mUsageStatsService = usageStatsManager;
2493    }
2494
2495    public void startObservingNativeCrashes() {
2496        final NativeCrashListener ncl = new NativeCrashListener(this);
2497        ncl.start();
2498    }
2499
2500    public IAppOpsService getAppOpsService() {
2501        return mAppOpsService;
2502    }
2503
2504    static class MemBinder extends Binder {
2505        ActivityManagerService mActivityManagerService;
2506        MemBinder(ActivityManagerService activityManagerService) {
2507            mActivityManagerService = activityManagerService;
2508        }
2509
2510        @Override
2511        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2512            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2513                    != PackageManager.PERMISSION_GRANTED) {
2514                pw.println("Permission Denial: can't dump meminfo from from pid="
2515                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2516                        + " without permission " + android.Manifest.permission.DUMP);
2517                return;
2518            }
2519
2520            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2521        }
2522    }
2523
2524    static class GraphicsBinder extends Binder {
2525        ActivityManagerService mActivityManagerService;
2526        GraphicsBinder(ActivityManagerService activityManagerService) {
2527            mActivityManagerService = activityManagerService;
2528        }
2529
2530        @Override
2531        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2532            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2533                    != PackageManager.PERMISSION_GRANTED) {
2534                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2535                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2536                        + " without permission " + android.Manifest.permission.DUMP);
2537                return;
2538            }
2539
2540            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2541        }
2542    }
2543
2544    static class DbBinder extends Binder {
2545        ActivityManagerService mActivityManagerService;
2546        DbBinder(ActivityManagerService activityManagerService) {
2547            mActivityManagerService = activityManagerService;
2548        }
2549
2550        @Override
2551        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2552            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2553                    != PackageManager.PERMISSION_GRANTED) {
2554                pw.println("Permission Denial: can't dump dbinfo from from pid="
2555                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2556                        + " without permission " + android.Manifest.permission.DUMP);
2557                return;
2558            }
2559
2560            mActivityManagerService.dumpDbInfo(fd, pw, args);
2561        }
2562    }
2563
2564    static class CpuBinder extends Binder {
2565        ActivityManagerService mActivityManagerService;
2566        CpuBinder(ActivityManagerService activityManagerService) {
2567            mActivityManagerService = activityManagerService;
2568        }
2569
2570        @Override
2571        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2572            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2573                    != PackageManager.PERMISSION_GRANTED) {
2574                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2575                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2576                        + " without permission " + android.Manifest.permission.DUMP);
2577                return;
2578            }
2579
2580            synchronized (mActivityManagerService.mProcessCpuTracker) {
2581                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2582                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2583                        SystemClock.uptimeMillis()));
2584            }
2585        }
2586    }
2587
2588    public static final class Lifecycle extends SystemService {
2589        private final ActivityManagerService mService;
2590
2591        public Lifecycle(Context context) {
2592            super(context);
2593            mService = new ActivityManagerService(context);
2594        }
2595
2596        @Override
2597        public void onStart() {
2598            mService.start();
2599        }
2600
2601        public ActivityManagerService getService() {
2602            return mService;
2603        }
2604    }
2605
2606    // Note: This method is invoked on the main thread but may need to attach various
2607    // handlers to other threads.  So take care to be explicit about the looper.
2608    public ActivityManagerService(Context systemContext) {
2609        mContext = systemContext;
2610        mFactoryTest = FactoryTest.getMode();
2611        mSystemThread = ActivityThread.currentActivityThread();
2612
2613        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2614
2615        mPermissionReviewRequired = mContext.getResources().getBoolean(
2616                com.android.internal.R.bool.config_permissionReviewRequired);
2617
2618        mHandlerThread = new ServiceThread(TAG,
2619                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2620        mHandlerThread.start();
2621        mHandler = new MainHandler(mHandlerThread.getLooper());
2622        mUiHandler = new UiHandler();
2623
2624        mConstants = new ActivityManagerConstants(this, mHandler);
2625
2626        if (DEBUG_BACKGROUND_CHECK) {
2627            Slog.d(TAG, "Enforcing O+ bg restrictions: " + mConstants.ENFORCE_BG_CHECK);
2628            StringBuilder sb = new StringBuilder(200);
2629            sb.append("  ");
2630            for (String a : getBackgroundLaunchBroadcasts()) {
2631                sb.append(' '); sb.append(a);
2632            }
2633            Slog.d(TAG, "Background implicit broadcasts:");
2634            Slog.d(TAG, sb.toString());
2635        }
2636
2637        /* static; one-time init here */
2638        if (sKillHandler == null) {
2639            sKillThread = new ServiceThread(TAG + ":kill",
2640                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2641            sKillThread.start();
2642            sKillHandler = new KillHandler(sKillThread.getLooper());
2643        }
2644
2645        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2646                "foreground", BROADCAST_FG_TIMEOUT, false);
2647        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2648                "background", BROADCAST_BG_TIMEOUT, true);
2649        mBroadcastQueues[0] = mFgBroadcastQueue;
2650        mBroadcastQueues[1] = mBgBroadcastQueue;
2651
2652        mServices = new ActiveServices(this);
2653        mProviderMap = new ProviderMap(this);
2654        mAppErrors = new AppErrors(mContext, this);
2655
2656        // TODO: Move creation of battery stats service outside of activity manager service.
2657        File dataDir = Environment.getDataDirectory();
2658        File systemDir = new File(dataDir, "system");
2659        systemDir.mkdirs();
2660        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2661        mBatteryStatsService.getActiveStatistics().readLocked();
2662        mBatteryStatsService.scheduleWriteToDisk();
2663        mOnBattery = DEBUG_POWER ? true
2664                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2665        mBatteryStatsService.getActiveStatistics().setCallback(this);
2666
2667        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2668
2669        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2670        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2671                new IAppOpsCallback.Stub() {
2672                    @Override public void opChanged(int op, int uid, String packageName) {
2673                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2674                            if (mAppOpsService.checkOperation(op, uid, packageName)
2675                                    != AppOpsManager.MODE_ALLOWED) {
2676                                runInBackgroundDisabled(uid);
2677                            }
2678                        }
2679                    }
2680                });
2681
2682        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2683
2684        mUserController = new UserController(this);
2685
2686        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2687            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2688
2689        if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2690            mUseFifoUiScheduling = true;
2691        }
2692
2693        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2694        mTempConfig.setToDefaults();
2695        mTempConfig.setLocales(LocaleList.getDefault());
2696        mConfigurationSeq = mTempConfig.seq = 1;
2697        mStackSupervisor = new ActivityStackSupervisor(this);
2698        mStackSupervisor.onConfigurationChanged(mTempConfig);
2699        mKeyguardController = mStackSupervisor.mKeyguardController;
2700        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2701        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2702        mTaskChangeNotificationController =
2703                new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
2704        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2705        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2706
2707        mProcessCpuThread = new Thread("CpuTracker") {
2708            @Override
2709            public void run() {
2710                synchronized (mProcessCpuTracker) {
2711                    mProcessCpuInitLatch.countDown();
2712                    mProcessCpuTracker.init();
2713                }
2714                while (true) {
2715                    try {
2716                        try {
2717                            synchronized(this) {
2718                                final long now = SystemClock.uptimeMillis();
2719                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2720                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2721                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2722                                //        + ", write delay=" + nextWriteDelay);
2723                                if (nextWriteDelay < nextCpuDelay) {
2724                                    nextCpuDelay = nextWriteDelay;
2725                                }
2726                                if (nextCpuDelay > 0) {
2727                                    mProcessCpuMutexFree.set(true);
2728                                    this.wait(nextCpuDelay);
2729                                }
2730                            }
2731                        } catch (InterruptedException e) {
2732                        }
2733                        updateCpuStatsNow();
2734                    } catch (Exception e) {
2735                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2736                    }
2737                }
2738            }
2739        };
2740
2741        Watchdog.getInstance().addMonitor(this);
2742        Watchdog.getInstance().addThread(mHandler);
2743    }
2744
2745    public void setSystemServiceManager(SystemServiceManager mgr) {
2746        mSystemServiceManager = mgr;
2747    }
2748
2749    public void setInstaller(Installer installer) {
2750        mInstaller = installer;
2751    }
2752
2753    private void start() {
2754        Process.removeAllProcessGroups();
2755        mProcessCpuThread.start();
2756
2757        mBatteryStatsService.publish(mContext);
2758        mAppOpsService.publish(mContext);
2759        Slog.d("AppOps", "AppOpsService published");
2760        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2761        // Wait for the synchronized block started in mProcessCpuThread,
2762        // so that any other acccess to mProcessCpuTracker from main thread
2763        // will be blocked during mProcessCpuTracker initialization.
2764        try {
2765            mProcessCpuInitLatch.await();
2766        } catch (InterruptedException e) {
2767            Slog.wtf(TAG, "Interrupted wait during start", e);
2768            Thread.currentThread().interrupt();
2769            throw new IllegalStateException("Interrupted wait during start");
2770        }
2771    }
2772
2773    void onUserStoppedLocked(int userId) {
2774        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2775    }
2776
2777    public void initPowerManagement() {
2778        mStackSupervisor.initPowerManagement();
2779        mBatteryStatsService.initPowerManagement();
2780        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2781        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2782        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2783        mVoiceWakeLock.setReferenceCounted(false);
2784    }
2785
2786    private ArraySet<String> getBackgroundLaunchBroadcasts() {
2787        if (mBackgroundLaunchBroadcasts == null) {
2788            mBackgroundLaunchBroadcasts = SystemConfig.getInstance().getAllowImplicitBroadcasts();
2789        }
2790        return mBackgroundLaunchBroadcasts;
2791    }
2792
2793    @Override
2794    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2795            throws RemoteException {
2796        if (code == SYSPROPS_TRANSACTION) {
2797            // We need to tell all apps about the system property change.
2798            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2799            synchronized(this) {
2800                final int NP = mProcessNames.getMap().size();
2801                for (int ip=0; ip<NP; ip++) {
2802                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2803                    final int NA = apps.size();
2804                    for (int ia=0; ia<NA; ia++) {
2805                        ProcessRecord app = apps.valueAt(ia);
2806                        if (app.thread != null) {
2807                            procs.add(app.thread.asBinder());
2808                        }
2809                    }
2810                }
2811            }
2812
2813            int N = procs.size();
2814            for (int i=0; i<N; i++) {
2815                Parcel data2 = Parcel.obtain();
2816                try {
2817                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null,
2818                            Binder.FLAG_ONEWAY);
2819                } catch (RemoteException e) {
2820                }
2821                data2.recycle();
2822            }
2823        }
2824        try {
2825            return super.onTransact(code, data, reply, flags);
2826        } catch (RuntimeException e) {
2827            // The activity manager only throws security exceptions, so let's
2828            // log all others.
2829            if (!(e instanceof SecurityException)) {
2830                Slog.wtf(TAG, "Activity Manager Crash", e);
2831            }
2832            throw e;
2833        }
2834    }
2835
2836    void updateCpuStats() {
2837        final long now = SystemClock.uptimeMillis();
2838        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2839            return;
2840        }
2841        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2842            synchronized (mProcessCpuThread) {
2843                mProcessCpuThread.notify();
2844            }
2845        }
2846    }
2847
2848    void updateCpuStatsNow() {
2849        synchronized (mProcessCpuTracker) {
2850            mProcessCpuMutexFree.set(false);
2851            final long now = SystemClock.uptimeMillis();
2852            boolean haveNewCpuStats = false;
2853
2854            if (MONITOR_CPU_USAGE &&
2855                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2856                mLastCpuTime.set(now);
2857                mProcessCpuTracker.update();
2858                if (mProcessCpuTracker.hasGoodLastStats()) {
2859                    haveNewCpuStats = true;
2860                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2861                    //Slog.i(TAG, "Total CPU usage: "
2862                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2863
2864                    // Slog the cpu usage if the property is set.
2865                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2866                        int user = mProcessCpuTracker.getLastUserTime();
2867                        int system = mProcessCpuTracker.getLastSystemTime();
2868                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2869                        int irq = mProcessCpuTracker.getLastIrqTime();
2870                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2871                        int idle = mProcessCpuTracker.getLastIdleTime();
2872
2873                        int total = user + system + iowait + irq + softIrq + idle;
2874                        if (total == 0) total = 1;
2875
2876                        EventLog.writeEvent(EventLogTags.CPU,
2877                                ((user+system+iowait+irq+softIrq) * 100) / total,
2878                                (user * 100) / total,
2879                                (system * 100) / total,
2880                                (iowait * 100) / total,
2881                                (irq * 100) / total,
2882                                (softIrq * 100) / total);
2883                    }
2884                }
2885            }
2886
2887            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2888            synchronized(bstats) {
2889                synchronized(mPidsSelfLocked) {
2890                    if (haveNewCpuStats) {
2891                        if (bstats.startAddingCpuLocked()) {
2892                            int totalUTime = 0;
2893                            int totalSTime = 0;
2894                            final int N = mProcessCpuTracker.countStats();
2895                            for (int i=0; i<N; i++) {
2896                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2897                                if (!st.working) {
2898                                    continue;
2899                                }
2900                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2901                                totalUTime += st.rel_utime;
2902                                totalSTime += st.rel_stime;
2903                                if (pr != null) {
2904                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2905                                    if (ps == null || !ps.isActive()) {
2906                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2907                                                pr.info.uid, pr.processName);
2908                                    }
2909                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2910                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2911                                } else {
2912                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2913                                    if (ps == null || !ps.isActive()) {
2914                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2915                                                bstats.mapUid(st.uid), st.name);
2916                                    }
2917                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2918                                }
2919                            }
2920                            final int userTime = mProcessCpuTracker.getLastUserTime();
2921                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2922                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2923                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2924                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2925                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2926                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2927                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2928                        }
2929                    }
2930                }
2931
2932                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2933                    mLastWriteTime = now;
2934                    mBatteryStatsService.scheduleWriteToDisk();
2935                }
2936            }
2937        }
2938    }
2939
2940    @Override
2941    public void batteryNeedsCpuUpdate() {
2942        updateCpuStatsNow();
2943    }
2944
2945    @Override
2946    public void batteryPowerChanged(boolean onBattery) {
2947        // When plugging in, update the CPU stats first before changing
2948        // the plug state.
2949        updateCpuStatsNow();
2950        synchronized (this) {
2951            synchronized(mPidsSelfLocked) {
2952                mOnBattery = DEBUG_POWER ? true : onBattery;
2953            }
2954        }
2955    }
2956
2957    @Override
2958    public void batterySendBroadcast(Intent intent) {
2959        synchronized (this) {
2960            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2961                    AppOpsManager.OP_NONE, null, false, false,
2962                    -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2963        }
2964    }
2965
2966    /**
2967     * Initialize the application bind args. These are passed to each
2968     * process when the bindApplication() IPC is sent to the process. They're
2969     * lazily setup to make sure the services are running when they're asked for.
2970     */
2971    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2972        // Isolated processes won't get this optimization, so that we don't
2973        // violate the rules about which services they have access to.
2974        if (isolated) {
2975            if (mIsolatedAppBindArgs == null) {
2976                mIsolatedAppBindArgs = new HashMap<>();
2977                mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
2978            }
2979            return mIsolatedAppBindArgs;
2980        }
2981
2982        if (mAppBindArgs == null) {
2983            mAppBindArgs = new HashMap<>();
2984
2985            // Setup the application init args
2986            mAppBindArgs.put("package", ServiceManager.getService("package"));
2987            mAppBindArgs.put("window", ServiceManager.getService("window"));
2988            mAppBindArgs.put(Context.ALARM_SERVICE,
2989                    ServiceManager.getService(Context.ALARM_SERVICE));
2990        }
2991        return mAppBindArgs;
2992    }
2993
2994    /**
2995     * Update AMS states when an activity is resumed. This should only be called by
2996     * {@link ActivityStack#setResumedActivityLocked} when an activity is resumed.
2997     */
2998    void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
2999        if (r.task.isApplicationTask()) {
3000            if (mCurAppTimeTracker != r.appTimeTracker) {
3001                // We are switching app tracking.  Complete the current one.
3002                if (mCurAppTimeTracker != null) {
3003                    mCurAppTimeTracker.stop();
3004                    mHandler.obtainMessage(
3005                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
3006                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
3007                    mCurAppTimeTracker = null;
3008                }
3009                if (r.appTimeTracker != null) {
3010                    mCurAppTimeTracker = r.appTimeTracker;
3011                    startTimeTrackingFocusedActivityLocked();
3012                }
3013            } else {
3014                startTimeTrackingFocusedActivityLocked();
3015            }
3016        } else {
3017            r.appTimeTracker = null;
3018        }
3019        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3020        // TODO: Probably not, because we don't want to resume voice on switching
3021        // back to this activity
3022        if (r.task.voiceInteractor != null) {
3023            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
3024        } else {
3025            finishRunningVoiceLocked();
3026            IVoiceInteractionSession session;
3027            if (mLastResumedActivity != null
3028                    && ((session = mLastResumedActivity.task.voiceSession) != null
3029                    || (session = mLastResumedActivity.voiceSession) != null)) {
3030                // We had been in a voice interaction session, but now focused has
3031                // move to something different.  Just finish the session, we can't
3032                // return to it and retain the proper state and synchronization with
3033                // the voice interaction service.
3034                finishVoiceTask(session);
3035            }
3036        }
3037
3038        mWindowManager.setFocusedApp(r.appToken, true);
3039
3040        applyUpdateLockStateLocked(r);
3041        applyUpdateVrModeLocked(r);
3042        if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
3043            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3044            mHandler.obtainMessage(
3045                    FOREGROUND_PROFILE_CHANGED_MSG, r.userId, 0).sendToTarget();
3046        }
3047
3048        mLastResumedActivity = r;
3049
3050        EventLogTags.writeAmSetResumedActivity(
3051                r == null ? -1 : r.userId,
3052                r == null ? "NULL" : r.shortComponentName,
3053                reason);
3054    }
3055
3056    @Override
3057    public void setFocusedStack(int stackId) {
3058        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3059        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3060        final long callingId = Binder.clearCallingIdentity();
3061        try {
3062            synchronized (this) {
3063                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3064                if (stack == null) {
3065                    return;
3066                }
3067                final ActivityRecord r = stack.topRunningActivityLocked();
3068                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
3069                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3070                }
3071            }
3072        } finally {
3073            Binder.restoreCallingIdentity(callingId);
3074        }
3075    }
3076
3077    @Override
3078    public void setFocusedTask(int taskId) {
3079        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3080        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3081        final long callingId = Binder.clearCallingIdentity();
3082        try {
3083            synchronized (this) {
3084                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3085                if (task == null) {
3086                    return;
3087                }
3088                final ActivityRecord r = task.topRunningActivityLocked();
3089                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
3090                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3091                }
3092            }
3093        } finally {
3094            Binder.restoreCallingIdentity(callingId);
3095        }
3096    }
3097
3098    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3099    @Override
3100    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3101        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3102        mTaskChangeNotificationController.registerTaskStackListener(listener);
3103    }
3104
3105    /**
3106     * Unregister a task stack listener so that it stops receiving callbacks.
3107     */
3108    @Override
3109    public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
3110         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "unregisterTaskStackListener()");
3111         mTaskChangeNotificationController.unregisterTaskStackListener(listener);
3112     }
3113
3114    @Override
3115    public void notifyActivityDrawn(IBinder token) {
3116        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3117        synchronized (this) {
3118            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3119            if (r != null) {
3120                r.getStack().notifyActivityDrawnLocked(r);
3121            }
3122        }
3123    }
3124
3125    final void applyUpdateLockStateLocked(ActivityRecord r) {
3126        // Modifications to the UpdateLock state are done on our handler, outside
3127        // the activity manager's locks.  The new state is determined based on the
3128        // state *now* of the relevant activity record.  The object is passed to
3129        // the handler solely for logging detail, not to be consulted/modified.
3130        final boolean nextState = r != null && r.immersive;
3131        mHandler.sendMessage(
3132                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3133    }
3134
3135    final void applyUpdateVrModeLocked(ActivityRecord r) {
3136        mHandler.sendMessage(
3137                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3138    }
3139
3140    private void sendNotifyVrManagerOfSleepState(boolean isSleeping) {
3141        mHandler.sendMessage(
3142                mHandler.obtainMessage(NOTIFY_VR_SLEEPING_MSG, isSleeping ? 1 : 0, 0));
3143    }
3144
3145    private void notifyVrManagerOfSleepState(boolean isSleeping) {
3146        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3147        if (vrService == null) {
3148            return;
3149        }
3150        vrService.onSleepStateChanged(isSleeping);
3151    }
3152
3153    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3154        Message msg = Message.obtain();
3155        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3156        msg.obj = r.task.askedCompatMode ? null : r;
3157        mUiHandler.sendMessage(msg);
3158    }
3159
3160    final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3161        final Configuration globalConfig = getGlobalConfiguration();
3162        if (globalConfig.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3163                && r.appInfo.requiresSmallestWidthDp > globalConfig.smallestScreenWidthDp) {
3164            final Message msg = Message.obtain();
3165            msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3166            msg.obj = r;
3167            mUiHandler.sendMessage(msg);
3168        }
3169    }
3170
3171    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3172            String what, Object obj, ProcessRecord srcApp) {
3173        app.lastActivityTime = now;
3174
3175        if (app.activities.size() > 0) {
3176            // Don't want to touch dependent processes that are hosting activities.
3177            return index;
3178        }
3179
3180        int lrui = mLruProcesses.lastIndexOf(app);
3181        if (lrui < 0) {
3182            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3183                    + what + " " + obj + " from " + srcApp);
3184            return index;
3185        }
3186
3187        if (lrui >= index) {
3188            // Don't want to cause this to move dependent processes *back* in the
3189            // list as if they were less frequently used.
3190            return index;
3191        }
3192
3193        if (lrui >= mLruProcessActivityStart) {
3194            // Don't want to touch dependent processes that are hosting activities.
3195            return index;
3196        }
3197
3198        mLruProcesses.remove(lrui);
3199        if (index > 0) {
3200            index--;
3201        }
3202        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3203                + " in LRU list: " + app);
3204        mLruProcesses.add(index, app);
3205        return index;
3206    }
3207
3208    static void killProcessGroup(int uid, int pid) {
3209        if (sKillHandler != null) {
3210            sKillHandler.sendMessage(
3211                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3212        } else {
3213            Slog.w(TAG, "Asked to kill process group before system bringup!");
3214            Process.killProcessGroup(uid, pid);
3215        }
3216    }
3217
3218    final void removeLruProcessLocked(ProcessRecord app) {
3219        int lrui = mLruProcesses.lastIndexOf(app);
3220        if (lrui >= 0) {
3221            if (!app.killed) {
3222                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3223                Process.killProcessQuiet(app.pid);
3224                killProcessGroup(app.uid, app.pid);
3225            }
3226            if (lrui <= mLruProcessActivityStart) {
3227                mLruProcessActivityStart--;
3228            }
3229            if (lrui <= mLruProcessServiceStart) {
3230                mLruProcessServiceStart--;
3231            }
3232            mLruProcesses.remove(lrui);
3233        }
3234    }
3235
3236    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3237            ProcessRecord client) {
3238        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3239                || app.treatLikeActivity;
3240        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3241        if (!activityChange && hasActivity) {
3242            // The process has activities, so we are only allowing activity-based adjustments
3243            // to move it.  It should be kept in the front of the list with other
3244            // processes that have activities, and we don't want those to change their
3245            // order except due to activity operations.
3246            return;
3247        }
3248
3249        mLruSeq++;
3250        final long now = SystemClock.uptimeMillis();
3251        app.lastActivityTime = now;
3252
3253        // First a quick reject: if the app is already at the position we will
3254        // put it, then there is nothing to do.
3255        if (hasActivity) {
3256            final int N = mLruProcesses.size();
3257            if (N > 0 && mLruProcesses.get(N-1) == app) {
3258                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3259                return;
3260            }
3261        } else {
3262            if (mLruProcessServiceStart > 0
3263                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3264                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3265                return;
3266            }
3267        }
3268
3269        int lrui = mLruProcesses.lastIndexOf(app);
3270
3271        if (app.persistent && lrui >= 0) {
3272            // We don't care about the position of persistent processes, as long as
3273            // they are in the list.
3274            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3275            return;
3276        }
3277
3278        /* In progress: compute new position first, so we can avoid doing work
3279           if the process is not actually going to move.  Not yet working.
3280        int addIndex;
3281        int nextIndex;
3282        boolean inActivity = false, inService = false;
3283        if (hasActivity) {
3284            // Process has activities, put it at the very tipsy-top.
3285            addIndex = mLruProcesses.size();
3286            nextIndex = mLruProcessServiceStart;
3287            inActivity = true;
3288        } else if (hasService) {
3289            // Process has services, put it at the top of the service list.
3290            addIndex = mLruProcessActivityStart;
3291            nextIndex = mLruProcessServiceStart;
3292            inActivity = true;
3293            inService = true;
3294        } else  {
3295            // Process not otherwise of interest, it goes to the top of the non-service area.
3296            addIndex = mLruProcessServiceStart;
3297            if (client != null) {
3298                int clientIndex = mLruProcesses.lastIndexOf(client);
3299                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3300                        + app);
3301                if (clientIndex >= 0 && addIndex > clientIndex) {
3302                    addIndex = clientIndex;
3303                }
3304            }
3305            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3306        }
3307
3308        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3309                + mLruProcessActivityStart + "): " + app);
3310        */
3311
3312        if (lrui >= 0) {
3313            if (lrui < mLruProcessActivityStart) {
3314                mLruProcessActivityStart--;
3315            }
3316            if (lrui < mLruProcessServiceStart) {
3317                mLruProcessServiceStart--;
3318            }
3319            /*
3320            if (addIndex > lrui) {
3321                addIndex--;
3322            }
3323            if (nextIndex > lrui) {
3324                nextIndex--;
3325            }
3326            */
3327            mLruProcesses.remove(lrui);
3328        }
3329
3330        /*
3331        mLruProcesses.add(addIndex, app);
3332        if (inActivity) {
3333            mLruProcessActivityStart++;
3334        }
3335        if (inService) {
3336            mLruProcessActivityStart++;
3337        }
3338        */
3339
3340        int nextIndex;
3341        if (hasActivity) {
3342            final int N = mLruProcesses.size();
3343            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3344                // Process doesn't have activities, but has clients with
3345                // activities...  move it up, but one below the top (the top
3346                // should always have a real activity).
3347                if (DEBUG_LRU) Slog.d(TAG_LRU,
3348                        "Adding to second-top of LRU activity list: " + app);
3349                mLruProcesses.add(N - 1, app);
3350                // To keep it from spamming the LRU list (by making a bunch of clients),
3351                // we will push down any other entries owned by the app.
3352                final int uid = app.info.uid;
3353                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3354                    ProcessRecord subProc = mLruProcesses.get(i);
3355                    if (subProc.info.uid == uid) {
3356                        // We want to push this one down the list.  If the process after
3357                        // it is for the same uid, however, don't do so, because we don't
3358                        // want them internally to be re-ordered.
3359                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3360                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3361                                    "Pushing uid " + uid + " swapping at " + i + ": "
3362                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3363                            ProcessRecord tmp = mLruProcesses.get(i);
3364                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3365                            mLruProcesses.set(i - 1, tmp);
3366                            i--;
3367                        }
3368                    } else {
3369                        // A gap, we can stop here.
3370                        break;
3371                    }
3372                }
3373            } else {
3374                // Process has activities, put it at the very tipsy-top.
3375                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3376                mLruProcesses.add(app);
3377            }
3378            nextIndex = mLruProcessServiceStart;
3379        } else if (hasService) {
3380            // Process has services, put it at the top of the service list.
3381            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3382            mLruProcesses.add(mLruProcessActivityStart, app);
3383            nextIndex = mLruProcessServiceStart;
3384            mLruProcessActivityStart++;
3385        } else  {
3386            // Process not otherwise of interest, it goes to the top of the non-service area.
3387            int index = mLruProcessServiceStart;
3388            if (client != null) {
3389                // If there is a client, don't allow the process to be moved up higher
3390                // in the list than that client.
3391                int clientIndex = mLruProcesses.lastIndexOf(client);
3392                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3393                        + " when updating " + app);
3394                if (clientIndex <= lrui) {
3395                    // Don't allow the client index restriction to push it down farther in the
3396                    // list than it already is.
3397                    clientIndex = lrui;
3398                }
3399                if (clientIndex >= 0 && index > clientIndex) {
3400                    index = clientIndex;
3401                }
3402            }
3403            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3404            mLruProcesses.add(index, app);
3405            nextIndex = index-1;
3406            mLruProcessActivityStart++;
3407            mLruProcessServiceStart++;
3408        }
3409
3410        // If the app is currently using a content provider or service,
3411        // bump those processes as well.
3412        for (int j=app.connections.size()-1; j>=0; j--) {
3413            ConnectionRecord cr = app.connections.valueAt(j);
3414            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3415                    && cr.binding.service.app != null
3416                    && cr.binding.service.app.lruSeq != mLruSeq
3417                    && !cr.binding.service.app.persistent) {
3418                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3419                        "service connection", cr, app);
3420            }
3421        }
3422        for (int j=app.conProviders.size()-1; j>=0; j--) {
3423            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3424            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3425                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3426                        "provider reference", cpr, app);
3427            }
3428        }
3429    }
3430
3431    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3432        if (uid == Process.SYSTEM_UID) {
3433            // The system gets to run in any process.  If there are multiple
3434            // processes with the same uid, just pick the first (this
3435            // should never happen).
3436            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3437            if (procs == null) return null;
3438            final int procCount = procs.size();
3439            for (int i = 0; i < procCount; i++) {
3440                final int procUid = procs.keyAt(i);
3441                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3442                    // Don't use an app process or different user process for system component.
3443                    continue;
3444                }
3445                return procs.valueAt(i);
3446            }
3447        }
3448        ProcessRecord proc = mProcessNames.get(processName, uid);
3449        if (false && proc != null && !keepIfLarge
3450                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3451                && proc.lastCachedPss >= 4000) {
3452            // Turn this condition on to cause killing to happen regularly, for testing.
3453            if (proc.baseProcessTracker != null) {
3454                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3455            }
3456            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3457        } else if (proc != null && !keepIfLarge
3458                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3459                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3460            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3461            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3462                if (proc.baseProcessTracker != null) {
3463                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3464                }
3465                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3466            }
3467        }
3468        return proc;
3469    }
3470
3471    void notifyPackageUse(String packageName, int reason) {
3472        IPackageManager pm = AppGlobals.getPackageManager();
3473        try {
3474            pm.notifyPackageUse(packageName, reason);
3475        } catch (RemoteException e) {
3476        }
3477    }
3478
3479    boolean isNextTransitionForward() {
3480        int transit = mWindowManager.getPendingAppTransition();
3481        return transit == TRANSIT_ACTIVITY_OPEN
3482                || transit == TRANSIT_TASK_OPEN
3483                || transit == TRANSIT_TASK_TO_FRONT;
3484    }
3485
3486    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3487            String processName, String abiOverride, int uid, Runnable crashHandler) {
3488        synchronized(this) {
3489            ApplicationInfo info = new ApplicationInfo();
3490            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3491            // For isolated processes, the former contains the parent's uid and the latter the
3492            // actual uid of the isolated process.
3493            // In the special case introduced by this method (which is, starting an isolated
3494            // process directly from the SystemServer without an actual parent app process) the
3495            // closest thing to a parent's uid is SYSTEM_UID.
3496            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3497            // the |isolated| logic in the ProcessRecord constructor.
3498            info.uid = Process.SYSTEM_UID;
3499            info.processName = processName;
3500            info.className = entryPoint;
3501            info.packageName = "android";
3502            info.seInfoUser = SELinuxUtil.COMPLETE_STR;
3503            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3504                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3505                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3506                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3507                    crashHandler);
3508            return proc != null ? proc.pid : 0;
3509        }
3510    }
3511
3512    final ProcessRecord startProcessLocked(String processName,
3513            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3514            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3515            boolean isolated, boolean keepIfLarge) {
3516        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3517                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3518                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3519                null /* crashHandler */);
3520    }
3521
3522    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3523            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3524            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3525            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3526        long startTime = SystemClock.elapsedRealtime();
3527        ProcessRecord app;
3528        if (!isolated) {
3529            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3530            checkTime(startTime, "startProcess: after getProcessRecord");
3531
3532            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3533                // If we are in the background, then check to see if this process
3534                // is bad.  If so, we will just silently fail.
3535                if (mAppErrors.isBadProcessLocked(info)) {
3536                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3537                            + "/" + info.processName);
3538                    return null;
3539                }
3540            } else {
3541                // When the user is explicitly starting a process, then clear its
3542                // crash count so that we won't make it bad until they see at
3543                // least one crash dialog again, and make the process good again
3544                // if it had been bad.
3545                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3546                        + "/" + info.processName);
3547                mAppErrors.resetProcessCrashTimeLocked(info);
3548                if (mAppErrors.isBadProcessLocked(info)) {
3549                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3550                            UserHandle.getUserId(info.uid), info.uid,
3551                            info.processName);
3552                    mAppErrors.clearBadProcessLocked(info);
3553                    if (app != null) {
3554                        app.bad = false;
3555                    }
3556                }
3557            }
3558        } else {
3559            // If this is an isolated process, it can't re-use an existing process.
3560            app = null;
3561        }
3562
3563        // We don't have to do anything more if:
3564        // (1) There is an existing application record; and
3565        // (2) The caller doesn't think it is dead, OR there is no thread
3566        //     object attached to it so we know it couldn't have crashed; and
3567        // (3) There is a pid assigned to it, so it is either starting or
3568        //     already running.
3569        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3570                + " app=" + app + " knownToBeDead=" + knownToBeDead
3571                + " thread=" + (app != null ? app.thread : null)
3572                + " pid=" + (app != null ? app.pid : -1));
3573        if (app != null && app.pid > 0) {
3574            if ((!knownToBeDead && !app.killed) || app.thread == null) {
3575                // We already have the app running, or are waiting for it to
3576                // come up (we have a pid but not yet its thread), so keep it.
3577                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3578                // If this is a new package in the process, add the package to the list
3579                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3580                checkTime(startTime, "startProcess: done, added package to proc");
3581                return app;
3582            }
3583
3584            // An application record is attached to a previous process,
3585            // clean it up now.
3586            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3587            checkTime(startTime, "startProcess: bad proc running, killing");
3588            killProcessGroup(app.uid, app.pid);
3589            handleAppDiedLocked(app, true, true);
3590            checkTime(startTime, "startProcess: done killing old proc");
3591        }
3592
3593        String hostingNameStr = hostingName != null
3594                ? hostingName.flattenToShortString() : null;
3595
3596        if (app == null) {
3597            checkTime(startTime, "startProcess: creating new process record");
3598            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3599            if (app == null) {
3600                Slog.w(TAG, "Failed making new process record for "
3601                        + processName + "/" + info.uid + " isolated=" + isolated);
3602                return null;
3603            }
3604            app.crashHandler = crashHandler;
3605            checkTime(startTime, "startProcess: done creating new process record");
3606        } else {
3607            // If this is a new package in the process, add the package to the list
3608            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3609            checkTime(startTime, "startProcess: added package to existing proc");
3610        }
3611
3612        // If the system is not ready yet, then hold off on starting this
3613        // process until it is.
3614        if (!mProcessesReady
3615                && !isAllowedWhileBooting(info)
3616                && !allowWhileBooting) {
3617            if (!mProcessesOnHold.contains(app)) {
3618                mProcessesOnHold.add(app);
3619            }
3620            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3621                    "System not ready, putting on hold: " + app);
3622            checkTime(startTime, "startProcess: returning with proc on hold");
3623            return app;
3624        }
3625
3626        checkTime(startTime, "startProcess: stepping in to startProcess");
3627        startProcessLocked(
3628                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3629        checkTime(startTime, "startProcess: done starting proc!");
3630        return (app.pid != 0) ? app : null;
3631    }
3632
3633    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3634        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3635    }
3636
3637    private final void startProcessLocked(ProcessRecord app,
3638            String hostingType, String hostingNameStr) {
3639        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3640                null /* entryPoint */, null /* entryPointArgs */);
3641    }
3642
3643    private final void startProcessLocked(ProcessRecord app, String hostingType,
3644            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3645        long startTime = SystemClock.elapsedRealtime();
3646        if (app.pid > 0 && app.pid != MY_PID) {
3647            checkTime(startTime, "startProcess: removing from pids map");
3648            synchronized (mPidsSelfLocked) {
3649                mPidsSelfLocked.remove(app.pid);
3650                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3651            }
3652            checkTime(startTime, "startProcess: done removing from pids map");
3653            app.setPid(0);
3654        }
3655
3656        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3657                "startProcessLocked removing on hold: " + app);
3658        mProcessesOnHold.remove(app);
3659
3660        checkTime(startTime, "startProcess: starting to update cpu stats");
3661        updateCpuStats();
3662        checkTime(startTime, "startProcess: done updating cpu stats");
3663
3664        try {
3665            try {
3666                final int userId = UserHandle.getUserId(app.uid);
3667                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3668            } catch (RemoteException e) {
3669                throw e.rethrowAsRuntimeException();
3670            }
3671
3672            int uid = app.uid;
3673            int[] gids = null;
3674            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3675            if (!app.isolated) {
3676                int[] permGids = null;
3677                try {
3678                    checkTime(startTime, "startProcess: getting gids from package manager");
3679                    final IPackageManager pm = AppGlobals.getPackageManager();
3680                    permGids = pm.getPackageGids(app.info.packageName,
3681                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3682                    StorageManagerInternal storageManagerInternal = LocalServices.getService(
3683                            StorageManagerInternal.class);
3684                    mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
3685                            app.info.packageName);
3686                } catch (RemoteException e) {
3687                    throw e.rethrowAsRuntimeException();
3688                }
3689
3690                /*
3691                 * Add shared application and profile GIDs so applications can share some
3692                 * resources like shared libraries and access user-wide resources
3693                 */
3694                if (ArrayUtils.isEmpty(permGids)) {
3695                    gids = new int[3];
3696                } else {
3697                    gids = new int[permGids.length + 3];
3698                    System.arraycopy(permGids, 0, gids, 3, permGids.length);
3699                }
3700                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3701                gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
3702                gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3703            }
3704            checkTime(startTime, "startProcess: building args");
3705            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3706                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3707                        && mTopComponent != null
3708                        && app.processName.equals(mTopComponent.getPackageName())) {
3709                    uid = 0;
3710                }
3711                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3712                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3713                    uid = 0;
3714                }
3715            }
3716            int debugFlags = 0;
3717            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3718                debugFlags |= Zygote.DEBUG_ENABLE_JDWP;
3719                debugFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
3720                // Also turn on CheckJNI for debuggable apps. It's quite
3721                // awkward to turn on otherwise.
3722                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3723            }
3724            // Run the app in safe mode if its manifest requests so or the
3725            // system is booted in safe mode.
3726            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3727                mSafeMode == true) {
3728                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3729            }
3730            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3731                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3732            }
3733            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3734            if ("true".equals(genDebugInfoProperty)) {
3735                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3736            }
3737            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3738                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3739            }
3740            if ("1".equals(SystemProperties.get("debug.assert"))) {
3741                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3742            }
3743            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3744                // Enable all debug flags required by the native debugger.
3745                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3746                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3747                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3748                mNativeDebuggingApp = null;
3749            }
3750
3751            String invokeWith = null;
3752            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3753                // Debuggable apps may include a wrapper script with their library directory.
3754                String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
3755                if (new File(wrapperFileName).exists()) {
3756                    invokeWith = "/system/bin/logwrapper " + wrapperFileName;
3757                }
3758            }
3759
3760            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3761            if (requiredAbi == null) {
3762                requiredAbi = Build.SUPPORTED_ABIS[0];
3763            }
3764
3765            String instructionSet = null;
3766            if (app.info.primaryCpuAbi != null) {
3767                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3768            }
3769
3770            app.gids = gids;
3771            app.requiredAbi = requiredAbi;
3772            app.instructionSet = instructionSet;
3773
3774            // the per-user SELinux context must be set
3775            if (TextUtils.isEmpty(app.info.seInfoUser)) {
3776                Slog.wtf(TAG, "SELinux tag not defined",
3777                        new IllegalStateException("SELinux tag not defined"));
3778            }
3779            final String seInfo = app.info.seInfo
3780                    + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
3781            // Start the process.  It will either succeed and return a result containing
3782            // the PID of the new process, or else throw a RuntimeException.
3783            boolean isActivityProcess = (entryPoint == null);
3784            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3785            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3786                    app.processName);
3787            checkTime(startTime, "startProcess: asking zygote to start proc");
3788            Process.ProcessStartResult startResult;
3789            if (hostingType.equals("webview_service")) {
3790                startResult = Process.startWebView(entryPoint,
3791                        app.processName, uid, uid, gids, debugFlags, mountExternal,
3792                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3793                        app.info.dataDir, null, entryPointArgs);
3794            } else {
3795                startResult = Process.start(entryPoint,
3796                        app.processName, uid, uid, gids, debugFlags, mountExternal,
3797                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3798                        app.info.dataDir, invokeWith, entryPointArgs);
3799            }
3800            checkTime(startTime, "startProcess: returned from zygote!");
3801            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3802
3803            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3804            checkTime(startTime, "startProcess: done updating battery stats");
3805
3806            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3807                    UserHandle.getUserId(uid), startResult.pid, uid,
3808                    app.processName, hostingType,
3809                    hostingNameStr != null ? hostingNameStr : "");
3810
3811            try {
3812                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3813                        seInfo, app.info.sourceDir, startResult.pid);
3814            } catch (RemoteException ex) {
3815                // Ignore
3816            }
3817
3818            if (app.persistent) {
3819                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3820            }
3821
3822            checkTime(startTime, "startProcess: building log message");
3823            StringBuilder buf = mStringBuilder;
3824            buf.setLength(0);
3825            buf.append("Start proc ");
3826            buf.append(startResult.pid);
3827            buf.append(':');
3828            buf.append(app.processName);
3829            buf.append('/');
3830            UserHandle.formatUid(buf, uid);
3831            if (!isActivityProcess) {
3832                buf.append(" [");
3833                buf.append(entryPoint);
3834                buf.append("]");
3835            }
3836            buf.append(" for ");
3837            buf.append(hostingType);
3838            if (hostingNameStr != null) {
3839                buf.append(" ");
3840                buf.append(hostingNameStr);
3841            }
3842            Slog.i(TAG, buf.toString());
3843            app.setPid(startResult.pid);
3844            app.usingWrapper = startResult.usingWrapper;
3845            app.removed = false;
3846            app.killed = false;
3847            app.killedByAm = false;
3848            checkTime(startTime, "startProcess: starting to update pids map");
3849            ProcessRecord oldApp;
3850            synchronized (mPidsSelfLocked) {
3851                oldApp = mPidsSelfLocked.get(startResult.pid);
3852            }
3853            // If there is already an app occupying that pid that hasn't been cleaned up
3854            if (oldApp != null && !app.isolated) {
3855                // Clean up anything relating to this pid first
3856                Slog.w(TAG, "Reusing pid " + startResult.pid
3857                        + " while app is still mapped to it");
3858                cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3859                        true /*replacingPid*/);
3860            }
3861            synchronized (mPidsSelfLocked) {
3862                this.mPidsSelfLocked.put(startResult.pid, app);
3863                if (isActivityProcess) {
3864                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3865                    msg.obj = app;
3866                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3867                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3868                }
3869            }
3870            checkTime(startTime, "startProcess: done updating pids map");
3871        } catch (RuntimeException e) {
3872            Slog.e(TAG, "Failure starting process " + app.processName, e);
3873
3874            // Something went very wrong while trying to start this process; one
3875            // common case is when the package is frozen due to an active
3876            // upgrade. To recover, clean up any active bookkeeping related to
3877            // starting this process. (We already invoked this method once when
3878            // the package was initially frozen through KILL_APPLICATION_MSG, so
3879            // it doesn't hurt to use it again.)
3880            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3881                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3882        }
3883    }
3884
3885    void updateUsageStats(ActivityRecord component, boolean resumed) {
3886        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3887                "updateUsageStats: comp=" + component + "res=" + resumed);
3888        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3889        if (resumed) {
3890            if (mUsageStatsService != null) {
3891                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3892                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3893            }
3894            synchronized (stats) {
3895                stats.noteActivityResumedLocked(component.app.uid);
3896            }
3897        } else {
3898            if (mUsageStatsService != null) {
3899                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3900                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3901            }
3902            synchronized (stats) {
3903                stats.noteActivityPausedLocked(component.app.uid);
3904            }
3905        }
3906    }
3907
3908    Intent getHomeIntent() {
3909        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3910        intent.setComponent(mTopComponent);
3911        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3912        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3913            intent.addCategory(Intent.CATEGORY_HOME);
3914        }
3915        return intent;
3916    }
3917
3918    boolean startHomeActivityLocked(int userId, String reason) {
3919        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3920                && mTopAction == null) {
3921            // We are running in factory test mode, but unable to find
3922            // the factory test app, so just sit around displaying the
3923            // error message and don't try to start anything.
3924            return false;
3925        }
3926        Intent intent = getHomeIntent();
3927        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3928        if (aInfo != null) {
3929            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3930            // Don't do this if the home app is currently being
3931            // instrumented.
3932            aInfo = new ActivityInfo(aInfo);
3933            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3934            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3935                    aInfo.applicationInfo.uid, true);
3936            if (app == null || app.instr == null) {
3937                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3938                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3939            }
3940        } else {
3941            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3942        }
3943
3944        return true;
3945    }
3946
3947    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3948        ActivityInfo ai = null;
3949        ComponentName comp = intent.getComponent();
3950        try {
3951            if (comp != null) {
3952                // Factory test.
3953                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3954            } else {
3955                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3956                        intent,
3957                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3958                        flags, userId);
3959
3960                if (info != null) {
3961                    ai = info.activityInfo;
3962                }
3963            }
3964        } catch (RemoteException e) {
3965            // ignore
3966        }
3967
3968        return ai;
3969    }
3970
3971    /**
3972     * Starts the "new version setup screen" if appropriate.
3973     */
3974    void startSetupActivityLocked() {
3975        // Only do this once per boot.
3976        if (mCheckedForSetup) {
3977            return;
3978        }
3979
3980        // We will show this screen if the current one is a different
3981        // version than the last one shown, and we are not running in
3982        // low-level factory test mode.
3983        final ContentResolver resolver = mContext.getContentResolver();
3984        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3985                Settings.Global.getInt(resolver,
3986                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3987            mCheckedForSetup = true;
3988
3989            // See if we should be showing the platform update setup UI.
3990            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3991            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3992                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3993            if (!ris.isEmpty()) {
3994                final ResolveInfo ri = ris.get(0);
3995                String vers = ri.activityInfo.metaData != null
3996                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3997                        : null;
3998                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3999                    vers = ri.activityInfo.applicationInfo.metaData.getString(
4000                            Intent.METADATA_SETUP_VERSION);
4001                }
4002                String lastVers = Settings.Secure.getString(
4003                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
4004                if (vers != null && !vers.equals(lastVers)) {
4005                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4006                    intent.setComponent(new ComponentName(
4007                            ri.activityInfo.packageName, ri.activityInfo.name));
4008                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
4009                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
4010                            null, 0, 0, 0, null, false, false, null, null, null);
4011                }
4012            }
4013        }
4014    }
4015
4016    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4017        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4018    }
4019
4020    void enforceNotIsolatedCaller(String caller) {
4021        if (UserHandle.isIsolated(Binder.getCallingUid())) {
4022            throw new SecurityException("Isolated process not allowed to call " + caller);
4023        }
4024    }
4025
4026    void enforceShellRestriction(String restriction, int userHandle) {
4027        if (Binder.getCallingUid() == Process.SHELL_UID) {
4028            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
4029                throw new SecurityException("Shell does not have permission to access user "
4030                        + userHandle);
4031            }
4032        }
4033    }
4034
4035    @Override
4036    public int getFrontActivityScreenCompatMode() {
4037        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4038        synchronized (this) {
4039            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4040        }
4041    }
4042
4043    @Override
4044    public void setFrontActivityScreenCompatMode(int mode) {
4045        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4046                "setFrontActivityScreenCompatMode");
4047        synchronized (this) {
4048            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4049        }
4050    }
4051
4052    @Override
4053    public int getPackageScreenCompatMode(String packageName) {
4054        enforceNotIsolatedCaller("getPackageScreenCompatMode");
4055        synchronized (this) {
4056            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4057        }
4058    }
4059
4060    @Override
4061    public void setPackageScreenCompatMode(String packageName, int mode) {
4062        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4063                "setPackageScreenCompatMode");
4064        synchronized (this) {
4065            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4066        }
4067    }
4068
4069    @Override
4070    public boolean getPackageAskScreenCompat(String packageName) {
4071        enforceNotIsolatedCaller("getPackageAskScreenCompat");
4072        synchronized (this) {
4073            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4074        }
4075    }
4076
4077    @Override
4078    public void setPackageAskScreenCompat(String packageName, boolean ask) {
4079        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4080                "setPackageAskScreenCompat");
4081        synchronized (this) {
4082            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4083        }
4084    }
4085
4086    private boolean hasUsageStatsPermission(String callingPackage) {
4087        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4088                Binder.getCallingUid(), callingPackage);
4089        if (mode == AppOpsManager.MODE_DEFAULT) {
4090            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4091                    == PackageManager.PERMISSION_GRANTED;
4092        }
4093        return mode == AppOpsManager.MODE_ALLOWED;
4094    }
4095
4096    @Override
4097    public int getPackageProcessState(String packageName, String callingPackage) {
4098        if (!hasUsageStatsPermission(callingPackage)) {
4099            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
4100                    "getPackageProcessState");
4101        }
4102
4103        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4104        synchronized (this) {
4105            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4106                final ProcessRecord proc = mLruProcesses.get(i);
4107                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4108                        || procState > proc.setProcState) {
4109                    if (proc.pkgList.containsKey(packageName)) {
4110                        procState = proc.setProcState;
4111                        break;
4112                    }
4113                    if (proc.pkgDeps != null && proc.pkgDeps.contains(packageName)) {
4114                        procState = proc.setProcState;
4115                    }
4116                }
4117            }
4118        }
4119        return procState;
4120    }
4121
4122    @Override
4123    public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4124            throws RemoteException {
4125        synchronized (this) {
4126            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4127            if (app == null) {
4128                throw new IllegalArgumentException("Unknown process: " + process);
4129            }
4130            if (app.thread == null) {
4131                throw new IllegalArgumentException("Process has no app thread");
4132            }
4133            if (app.trimMemoryLevel >= level) {
4134                throw new IllegalArgumentException(
4135                        "Unable to set a higher trim level than current level");
4136            }
4137            if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4138                    app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4139                throw new IllegalArgumentException("Unable to set a background trim level "
4140                    + "on a foreground process");
4141            }
4142            app.thread.scheduleTrimMemory(level);
4143            app.trimMemoryLevel = level;
4144            return true;
4145        }
4146    }
4147
4148    private void dispatchProcessesChanged() {
4149        int N;
4150        synchronized (this) {
4151            N = mPendingProcessChanges.size();
4152            if (mActiveProcessChanges.length < N) {
4153                mActiveProcessChanges = new ProcessChangeItem[N];
4154            }
4155            mPendingProcessChanges.toArray(mActiveProcessChanges);
4156            mPendingProcessChanges.clear();
4157            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4158                    "*** Delivering " + N + " process changes");
4159        }
4160
4161        int i = mProcessObservers.beginBroadcast();
4162        while (i > 0) {
4163            i--;
4164            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4165            if (observer != null) {
4166                try {
4167                    for (int j=0; j<N; j++) {
4168                        ProcessChangeItem item = mActiveProcessChanges[j];
4169                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4170                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4171                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4172                                    + item.uid + ": " + item.foregroundActivities);
4173                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4174                                    item.foregroundActivities);
4175                        }
4176                    }
4177                } catch (RemoteException e) {
4178                }
4179            }
4180        }
4181        mProcessObservers.finishBroadcast();
4182
4183        synchronized (this) {
4184            for (int j=0; j<N; j++) {
4185                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4186            }
4187        }
4188    }
4189
4190    private void dispatchProcessDied(int pid, int uid) {
4191        int i = mProcessObservers.beginBroadcast();
4192        while (i > 0) {
4193            i--;
4194            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4195            if (observer != null) {
4196                try {
4197                    observer.onProcessDied(pid, uid);
4198                } catch (RemoteException e) {
4199                }
4200            }
4201        }
4202        mProcessObservers.finishBroadcast();
4203    }
4204
4205    private void dispatchUidsChanged() {
4206        int N;
4207        synchronized (this) {
4208            N = mPendingUidChanges.size();
4209            if (mActiveUidChanges.length < N) {
4210                mActiveUidChanges = new UidRecord.ChangeItem[N];
4211            }
4212            for (int i=0; i<N; i++) {
4213                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4214                mActiveUidChanges[i] = change;
4215                if (change.uidRecord != null) {
4216                    change.uidRecord.pendingChange = null;
4217                    change.uidRecord = null;
4218                }
4219            }
4220            mPendingUidChanges.clear();
4221            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4222                    "*** Delivering " + N + " uid changes");
4223        }
4224
4225        int i = mUidObservers.beginBroadcast();
4226        while (i > 0) {
4227            i--;
4228            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4229            final UidObserverRegistration reg = (UidObserverRegistration)
4230                    mUidObservers.getBroadcastCookie(i);
4231            if (observer != null) {
4232                try {
4233                    for (int j=0; j<N; j++) {
4234                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4235                        final int change = item.change;
4236                        UidRecord validateUid = null;
4237                        if (VALIDATE_UID_STATES && i == 0) {
4238                            validateUid = mValidateUids.get(item.uid);
4239                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4240                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4241                                validateUid = new UidRecord(item.uid);
4242                                mValidateUids.put(item.uid, validateUid);
4243                            }
4244                        }
4245                        if (change == UidRecord.CHANGE_IDLE
4246                                || change == UidRecord.CHANGE_GONE_IDLE) {
4247                            if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4248                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4249                                        "UID idle uid=" + item.uid);
4250                                observer.onUidIdle(item.uid, item.ephemeral);
4251                            }
4252                            if (VALIDATE_UID_STATES && i == 0) {
4253                                if (validateUid != null) {
4254                                    validateUid.idle = true;
4255                                }
4256                            }
4257                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4258                            if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4259                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4260                                        "UID active uid=" + item.uid);
4261                                observer.onUidActive(item.uid);
4262                            }
4263                            if (VALIDATE_UID_STATES && i == 0) {
4264                                validateUid.idle = false;
4265                            }
4266                        }
4267                        if (change == UidRecord.CHANGE_GONE
4268                                || change == UidRecord.CHANGE_GONE_IDLE) {
4269                            if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4270                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4271                                        "UID gone uid=" + item.uid);
4272                                observer.onUidGone(item.uid, item.ephemeral);
4273                            }
4274                            if (reg.lastProcStates != null) {
4275                                reg.lastProcStates.delete(item.uid);
4276                            }
4277                            if (VALIDATE_UID_STATES && i == 0) {
4278                                if (validateUid != null) {
4279                                    mValidateUids.remove(item.uid);
4280                                }
4281                            }
4282                        } else {
4283                            if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4284                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4285                                        "UID CHANGED uid=" + item.uid
4286                                                + ": " + item.processState);
4287                                boolean doReport = true;
4288                                if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
4289                                    final int lastState = reg.lastProcStates.get(item.uid,
4290                                            ActivityManager.PROCESS_STATE_UNKNOWN);
4291                                    if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
4292                                        final boolean lastAboveCut = lastState <= reg.cutpoint;
4293                                        final boolean newAboveCut = item.processState <= reg.cutpoint;
4294                                        doReport = lastAboveCut != newAboveCut;
4295                                    } else {
4296                                        doReport = item.processState
4297                                                != ActivityManager.PROCESS_STATE_NONEXISTENT;
4298                                    }
4299                                }
4300                                if (doReport) {
4301                                    if (reg.lastProcStates != null) {
4302                                        reg.lastProcStates.put(item.uid, item.processState);
4303                                    }
4304                                    observer.onUidStateChanged(item.uid, item.processState);
4305                                }
4306                            }
4307                            if (VALIDATE_UID_STATES && i == 0) {
4308                                validateUid.curProcState = validateUid.setProcState
4309                                        = item.processState;
4310                            }
4311                        }
4312                    }
4313                } catch (RemoteException e) {
4314                }
4315            }
4316        }
4317        mUidObservers.finishBroadcast();
4318
4319        synchronized (this) {
4320            for (int j=0; j<N; j++) {
4321                mAvailUidChanges.add(mActiveUidChanges[j]);
4322            }
4323        }
4324    }
4325
4326    @Override
4327    public final int startActivity(IApplicationThread caller, String callingPackage,
4328            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4329            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4330        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4331                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4332                UserHandle.getCallingUserId());
4333    }
4334
4335    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4336        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4337        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4338                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4339                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4340
4341        // TODO: Switch to user app stacks here.
4342        String mimeType = intent.getType();
4343        final Uri data = intent.getData();
4344        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4345            mimeType = getProviderMimeType(data, userId);
4346        }
4347        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4348
4349        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4350        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4351                null, 0, 0, null, null, null, null, false, userId, container, null);
4352    }
4353
4354    @Override
4355    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4356            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4357            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4358        enforceNotIsolatedCaller("startActivity");
4359        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4360                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4361        // TODO: Switch to user app stacks here.
4362        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4363                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4364                profilerInfo, null, null, bOptions, false, userId, null, null);
4365    }
4366
4367    @Override
4368    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4369            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4370            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4371            int userId) {
4372
4373        // This is very dangerous -- it allows you to perform a start activity (including
4374        // permission grants) as any app that may launch one of your own activities.  So
4375        // we will only allow this to be done from activities that are part of the core framework,
4376        // and then only when they are running as the system.
4377        final ActivityRecord sourceRecord;
4378        final int targetUid;
4379        final String targetPackage;
4380        synchronized (this) {
4381            if (resultTo == null) {
4382                throw new SecurityException("Must be called from an activity");
4383            }
4384            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4385            if (sourceRecord == null) {
4386                throw new SecurityException("Called with bad activity token: " + resultTo);
4387            }
4388            if (!sourceRecord.info.packageName.equals("android")) {
4389                throw new SecurityException(
4390                        "Must be called from an activity that is declared in the android package");
4391            }
4392            if (sourceRecord.app == null) {
4393                throw new SecurityException("Called without a process attached to activity");
4394            }
4395            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4396                // This is still okay, as long as this activity is running under the
4397                // uid of the original calling activity.
4398                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4399                    throw new SecurityException(
4400                            "Calling activity in uid " + sourceRecord.app.uid
4401                                    + " must be system uid or original calling uid "
4402                                    + sourceRecord.launchedFromUid);
4403                }
4404            }
4405            if (ignoreTargetSecurity) {
4406                if (intent.getComponent() == null) {
4407                    throw new SecurityException(
4408                            "Component must be specified with ignoreTargetSecurity");
4409                }
4410                if (intent.getSelector() != null) {
4411                    throw new SecurityException(
4412                            "Selector not allowed with ignoreTargetSecurity");
4413                }
4414            }
4415            targetUid = sourceRecord.launchedFromUid;
4416            targetPackage = sourceRecord.launchedFromPackage;
4417        }
4418
4419        if (userId == UserHandle.USER_NULL) {
4420            userId = UserHandle.getUserId(sourceRecord.app.uid);
4421        }
4422
4423        // TODO: Switch to user app stacks here.
4424        try {
4425            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4426                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4427                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4428            return ret;
4429        } catch (SecurityException e) {
4430            // XXX need to figure out how to propagate to original app.
4431            // A SecurityException here is generally actually a fault of the original
4432            // calling activity (such as a fairly granting permissions), so propagate it
4433            // back to them.
4434            /*
4435            StringBuilder msg = new StringBuilder();
4436            msg.append("While launching");
4437            msg.append(intent.toString());
4438            msg.append(": ");
4439            msg.append(e.getMessage());
4440            */
4441            throw e;
4442        }
4443    }
4444
4445    @Override
4446    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4447            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4448            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4449        enforceNotIsolatedCaller("startActivityAndWait");
4450        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4451                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4452        WaitResult res = new WaitResult();
4453        // TODO: Switch to user app stacks here.
4454        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4455                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4456                bOptions, false, userId, null, null);
4457        return res;
4458    }
4459
4460    @Override
4461    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4462            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4463            int startFlags, Configuration config, Bundle bOptions, int userId) {
4464        enforceNotIsolatedCaller("startActivityWithConfig");
4465        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4466                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4467        // TODO: Switch to user app stacks here.
4468        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4469                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4470                null, null, config, bOptions, false, userId, null, null);
4471        return ret;
4472    }
4473
4474    @Override
4475    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4476            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4477            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4478            throws TransactionTooLargeException {
4479        enforceNotIsolatedCaller("startActivityIntentSender");
4480        // Refuse possible leaked file descriptors
4481        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4482            throw new IllegalArgumentException("File descriptors passed in Intent");
4483        }
4484
4485        IIntentSender sender = intent.getTarget();
4486        if (!(sender instanceof PendingIntentRecord)) {
4487            throw new IllegalArgumentException("Bad PendingIntent object");
4488        }
4489
4490        PendingIntentRecord pir = (PendingIntentRecord)sender;
4491
4492        synchronized (this) {
4493            // If this is coming from the currently resumed activity, it is
4494            // effectively saying that app switches are allowed at this point.
4495            final ActivityStack stack = getFocusedStack();
4496            if (stack.mResumedActivity != null &&
4497                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4498                mAppSwitchesAllowedTime = 0;
4499            }
4500        }
4501        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4502                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4503        return ret;
4504    }
4505
4506    @Override
4507    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4508            Intent intent, String resolvedType, IVoiceInteractionSession session,
4509            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4510            Bundle bOptions, int userId) {
4511        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4512                != PackageManager.PERMISSION_GRANTED) {
4513            String msg = "Permission Denial: startVoiceActivity() from pid="
4514                    + Binder.getCallingPid()
4515                    + ", uid=" + Binder.getCallingUid()
4516                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4517            Slog.w(TAG, msg);
4518            throw new SecurityException(msg);
4519        }
4520        if (session == null || interactor == null) {
4521            throw new NullPointerException("null session or interactor");
4522        }
4523        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4524                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4525        // TODO: Switch to user app stacks here.
4526        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4527                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4528                null, bOptions, false, userId, null, null);
4529    }
4530
4531    @Override
4532    public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
4533            Intent intent, String resolvedType, Bundle bOptions, int userId) {
4534        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4535                != PackageManager.PERMISSION_GRANTED) {
4536            final String msg = "Permission Denial: startAssistantActivity() from pid="
4537                    + Binder.getCallingPid()
4538                    + ", uid=" + Binder.getCallingUid()
4539                    + " requires " + Manifest.permission.BIND_VOICE_INTERACTION;
4540            Slog.w(TAG, msg);
4541            throw new SecurityException(msg);
4542        }
4543        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4544                ALLOW_FULL_ONLY, "startAssistantActivity", null);
4545        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4546                resolvedType, null, null, null, null, 0, 0, null, null, null, bOptions, false,
4547                userId, null, null);
4548    }
4549
4550    @Override
4551    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4552            throws RemoteException {
4553        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4554        synchronized (this) {
4555            ActivityRecord activity = getFocusedStack().topActivity();
4556            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4557                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4558            }
4559            if (mRunningVoice != null || activity.task.voiceSession != null
4560                    || activity.voiceSession != null) {
4561                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4562                return;
4563            }
4564            if (activity.pendingVoiceInteractionStart) {
4565                Slog.w(TAG, "Pending start of voice interaction already.");
4566                return;
4567            }
4568            activity.pendingVoiceInteractionStart = true;
4569        }
4570        LocalServices.getService(VoiceInteractionManagerInternal.class)
4571                .startLocalVoiceInteraction(callingActivity, options);
4572    }
4573
4574    @Override
4575    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4576        LocalServices.getService(VoiceInteractionManagerInternal.class)
4577                .stopLocalVoiceInteraction(callingActivity);
4578    }
4579
4580    @Override
4581    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4582        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4583                .supportsLocalVoiceInteraction();
4584    }
4585
4586    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4587            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4588        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4589        if (activityToCallback == null) return;
4590        activityToCallback.setVoiceSessionLocked(voiceSession);
4591
4592        // Inform the activity
4593        try {
4594            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4595                    voiceInteractor);
4596            long token = Binder.clearCallingIdentity();
4597            try {
4598                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4599            } finally {
4600                Binder.restoreCallingIdentity(token);
4601            }
4602            // TODO: VI Should we cache the activity so that it's easier to find later
4603            // rather than scan through all the stacks and activities?
4604        } catch (RemoteException re) {
4605            activityToCallback.clearVoiceSessionLocked();
4606            // TODO: VI Should this terminate the voice session?
4607        }
4608    }
4609
4610    @Override
4611    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4612        synchronized (this) {
4613            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4614                if (keepAwake) {
4615                    mVoiceWakeLock.acquire();
4616                } else {
4617                    mVoiceWakeLock.release();
4618                }
4619            }
4620        }
4621    }
4622
4623    @Override
4624    public boolean startNextMatchingActivity(IBinder callingActivity,
4625            Intent intent, Bundle bOptions) {
4626        // Refuse possible leaked file descriptors
4627        if (intent != null && intent.hasFileDescriptors() == true) {
4628            throw new IllegalArgumentException("File descriptors passed in Intent");
4629        }
4630        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4631
4632        synchronized (this) {
4633            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4634            if (r == null) {
4635                ActivityOptions.abort(options);
4636                return false;
4637            }
4638            if (r.app == null || r.app.thread == null) {
4639                // The caller is not running...  d'oh!
4640                ActivityOptions.abort(options);
4641                return false;
4642            }
4643            intent = new Intent(intent);
4644            // The caller is not allowed to change the data.
4645            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4646            // And we are resetting to find the next component...
4647            intent.setComponent(null);
4648
4649            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4650
4651            ActivityInfo aInfo = null;
4652            try {
4653                List<ResolveInfo> resolves =
4654                    AppGlobals.getPackageManager().queryIntentActivities(
4655                            intent, r.resolvedType,
4656                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4657                            UserHandle.getCallingUserId()).getList();
4658
4659                // Look for the original activity in the list...
4660                final int N = resolves != null ? resolves.size() : 0;
4661                for (int i=0; i<N; i++) {
4662                    ResolveInfo rInfo = resolves.get(i);
4663                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4664                            && rInfo.activityInfo.name.equals(r.info.name)) {
4665                        // We found the current one...  the next matching is
4666                        // after it.
4667                        i++;
4668                        if (i<N) {
4669                            aInfo = resolves.get(i).activityInfo;
4670                        }
4671                        if (debug) {
4672                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4673                                    + "/" + r.info.name);
4674                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4675                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4676                        }
4677                        break;
4678                    }
4679                }
4680            } catch (RemoteException e) {
4681            }
4682
4683            if (aInfo == null) {
4684                // Nobody who is next!
4685                ActivityOptions.abort(options);
4686                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4687                return false;
4688            }
4689
4690            intent.setComponent(new ComponentName(
4691                    aInfo.applicationInfo.packageName, aInfo.name));
4692            intent.setFlags(intent.getFlags()&~(
4693                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4694                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4695                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4696                    Intent.FLAG_ACTIVITY_NEW_TASK));
4697
4698            // Okay now we need to start the new activity, replacing the
4699            // currently running activity.  This is a little tricky because
4700            // we want to start the new one as if the current one is finished,
4701            // but not finish the current one first so that there is no flicker.
4702            // And thus...
4703            final boolean wasFinishing = r.finishing;
4704            r.finishing = true;
4705
4706            // Propagate reply information over to the new activity.
4707            final ActivityRecord resultTo = r.resultTo;
4708            final String resultWho = r.resultWho;
4709            final int requestCode = r.requestCode;
4710            r.resultTo = null;
4711            if (resultTo != null) {
4712                resultTo.removeResultsLocked(r, resultWho, requestCode);
4713            }
4714
4715            final long origId = Binder.clearCallingIdentity();
4716            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4717                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4718                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4719                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4720                    false, false, null, null, null);
4721            Binder.restoreCallingIdentity(origId);
4722
4723            r.finishing = wasFinishing;
4724            if (res != ActivityManager.START_SUCCESS) {
4725                return false;
4726            }
4727            return true;
4728        }
4729    }
4730
4731    @Override
4732    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4733        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4734            String msg = "Permission Denial: startActivityFromRecents called without " +
4735                    START_TASKS_FROM_RECENTS;
4736            Slog.w(TAG, msg);
4737            throw new SecurityException(msg);
4738        }
4739        final long origId = Binder.clearCallingIdentity();
4740        try {
4741            synchronized (this) {
4742                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4743            }
4744        } finally {
4745            Binder.restoreCallingIdentity(origId);
4746        }
4747    }
4748
4749    final int startActivityInPackage(int uid, String callingPackage,
4750            Intent intent, String resolvedType, IBinder resultTo,
4751            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4752            IActivityContainer container, TaskRecord inTask) {
4753
4754        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4755                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4756
4757        // TODO: Switch to user app stacks here.
4758        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4759                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4760                null, null, null, bOptions, false, userId, container, inTask);
4761        return ret;
4762    }
4763
4764    @Override
4765    public final int startActivities(IApplicationThread caller, String callingPackage,
4766            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4767            int userId) {
4768        enforceNotIsolatedCaller("startActivities");
4769        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4770                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4771        // TODO: Switch to user app stacks here.
4772        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4773                resolvedTypes, resultTo, bOptions, userId);
4774        return ret;
4775    }
4776
4777    final int startActivitiesInPackage(int uid, String callingPackage,
4778            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4779            Bundle bOptions, int userId) {
4780
4781        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4782                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4783        // TODO: Switch to user app stacks here.
4784        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4785                resultTo, bOptions, userId);
4786        return ret;
4787    }
4788
4789    @Override
4790    public void reportActivityFullyDrawn(IBinder token) {
4791        synchronized (this) {
4792            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4793            if (r == null) {
4794                return;
4795            }
4796            r.reportFullyDrawnLocked();
4797        }
4798    }
4799
4800    @Override
4801    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4802        synchronized (this) {
4803            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4804            if (r == null) {
4805                return;
4806            }
4807            final long origId = Binder.clearCallingIdentity();
4808            try {
4809                r.setRequestedOrientation(requestedOrientation);
4810            } finally {
4811                Binder.restoreCallingIdentity(origId);
4812            }
4813        }
4814    }
4815
4816    @Override
4817    public int getRequestedOrientation(IBinder token) {
4818        synchronized (this) {
4819            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4820            if (r == null) {
4821                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4822            }
4823            return r.getRequestedOrientation();
4824        }
4825    }
4826
4827    @Override
4828    public final void requestActivityRelaunch(IBinder token) {
4829        synchronized(this) {
4830            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4831            if (r == null) {
4832                return;
4833            }
4834            final long origId = Binder.clearCallingIdentity();
4835            try {
4836                r.forceNewConfig = true;
4837                r.ensureActivityConfigurationLocked(0 /* globalChanges */,
4838                        false /* preserveWindow */);
4839            } finally {
4840                Binder.restoreCallingIdentity(origId);
4841            }
4842        }
4843    }
4844
4845    /**
4846     * This is the internal entry point for handling Activity.finish().
4847     *
4848     * @param token The Binder token referencing the Activity we want to finish.
4849     * @param resultCode Result code, if any, from this Activity.
4850     * @param resultData Result data (Intent), if any, from this Activity.
4851     * @param finishTask Whether to finish the task associated with this Activity.
4852     *
4853     * @return Returns true if the activity successfully finished, or false if it is still running.
4854     */
4855    @Override
4856    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4857            int finishTask) {
4858        // Refuse possible leaked file descriptors
4859        if (resultData != null && resultData.hasFileDescriptors() == true) {
4860            throw new IllegalArgumentException("File descriptors passed in Intent");
4861        }
4862
4863        synchronized(this) {
4864            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4865            if (r == null) {
4866                return true;
4867            }
4868            // Keep track of the root activity of the task before we finish it
4869            TaskRecord tr = r.task;
4870            ActivityRecord rootR = tr.getRootActivity();
4871            if (rootR == null) {
4872                Slog.w(TAG, "Finishing task with all activities already finished");
4873            }
4874            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4875            // finish.
4876            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4877                    mStackSupervisor.isLastLockedTask(tr)) {
4878                Slog.i(TAG, "Not finishing task in lock task mode");
4879                mStackSupervisor.showLockTaskToast();
4880                return false;
4881            }
4882            if (mController != null) {
4883                // Find the first activity that is not finishing.
4884                ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
4885                if (next != null) {
4886                    // ask watcher if this is allowed
4887                    boolean resumeOK = true;
4888                    try {
4889                        resumeOK = mController.activityResuming(next.packageName);
4890                    } catch (RemoteException e) {
4891                        mController = null;
4892                        Watchdog.getInstance().setActivityController(null);
4893                    }
4894
4895                    if (!resumeOK) {
4896                        Slog.i(TAG, "Not finishing activity because controller resumed");
4897                        return false;
4898                    }
4899                }
4900            }
4901            final long origId = Binder.clearCallingIdentity();
4902            try {
4903                boolean res;
4904                final boolean finishWithRootActivity =
4905                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4906                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4907                        || (finishWithRootActivity && r == rootR)) {
4908                    // If requested, remove the task that is associated to this activity only if it
4909                    // was the root activity in the task. The result code and data is ignored
4910                    // because we don't support returning them across task boundaries. Also, to
4911                    // keep backwards compatibility we remove the task from recents when finishing
4912                    // task with root activity.
4913                    res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4914                    if (!res) {
4915                        Slog.i(TAG, "Removing task failed to finish activity");
4916                    }
4917                } else {
4918                    res = tr.getStack().requestFinishActivityLocked(token, resultCode,
4919                            resultData, "app-request", true);
4920                    if (!res) {
4921                        Slog.i(TAG, "Failed to finish by app-request");
4922                    }
4923                }
4924                return res;
4925            } finally {
4926                Binder.restoreCallingIdentity(origId);
4927            }
4928        }
4929    }
4930
4931    @Override
4932    public final void finishHeavyWeightApp() {
4933        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4934                != PackageManager.PERMISSION_GRANTED) {
4935            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4936                    + Binder.getCallingPid()
4937                    + ", uid=" + Binder.getCallingUid()
4938                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4939            Slog.w(TAG, msg);
4940            throw new SecurityException(msg);
4941        }
4942
4943        synchronized(this) {
4944            if (mHeavyWeightProcess == null) {
4945                return;
4946            }
4947
4948            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4949            for (int i = 0; i < activities.size(); i++) {
4950                ActivityRecord r = activities.get(i);
4951                if (!r.finishing && r.isInStackLocked()) {
4952                    r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
4953                            null, "finish-heavy", true);
4954                }
4955            }
4956
4957            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4958                    mHeavyWeightProcess.userId, 0));
4959            mHeavyWeightProcess = null;
4960        }
4961    }
4962
4963    @Override
4964    public void crashApplication(int uid, int initialPid, String packageName, int userId,
4965            String message) {
4966        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4967                != PackageManager.PERMISSION_GRANTED) {
4968            String msg = "Permission Denial: crashApplication() from pid="
4969                    + Binder.getCallingPid()
4970                    + ", uid=" + Binder.getCallingUid()
4971                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4972            Slog.w(TAG, msg);
4973            throw new SecurityException(msg);
4974        }
4975
4976        synchronized(this) {
4977            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
4978        }
4979    }
4980
4981    @Override
4982    public final void finishSubActivity(IBinder token, String resultWho,
4983            int requestCode) {
4984        synchronized(this) {
4985            final long origId = Binder.clearCallingIdentity();
4986            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4987            if (r != null) {
4988                r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
4989            }
4990            Binder.restoreCallingIdentity(origId);
4991        }
4992    }
4993
4994    @Override
4995    public boolean finishActivityAffinity(IBinder token) {
4996        synchronized(this) {
4997            final long origId = Binder.clearCallingIdentity();
4998            try {
4999                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5000                if (r == null) {
5001                    return false;
5002                }
5003
5004                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
5005                // can finish.
5006                final TaskRecord task = r.task;
5007                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
5008                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
5009                    mStackSupervisor.showLockTaskToast();
5010                    return false;
5011                }
5012                return task.getStack().finishActivityAffinityLocked(r);
5013            } finally {
5014                Binder.restoreCallingIdentity(origId);
5015            }
5016        }
5017    }
5018
5019    @Override
5020    public void finishVoiceTask(IVoiceInteractionSession session) {
5021        synchronized (this) {
5022            final long origId = Binder.clearCallingIdentity();
5023            try {
5024                // TODO: VI Consider treating local voice interactions and voice tasks
5025                // differently here
5026                mStackSupervisor.finishVoiceTask(session);
5027            } finally {
5028                Binder.restoreCallingIdentity(origId);
5029            }
5030        }
5031
5032    }
5033
5034    @Override
5035    public boolean releaseActivityInstance(IBinder token) {
5036        synchronized(this) {
5037            final long origId = Binder.clearCallingIdentity();
5038            try {
5039                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5040                if (r == null) {
5041                    return false;
5042                }
5043                return r.getStack().safelyDestroyActivityLocked(r, "app-req");
5044            } finally {
5045                Binder.restoreCallingIdentity(origId);
5046            }
5047        }
5048    }
5049
5050    @Override
5051    public void releaseSomeActivities(IApplicationThread appInt) {
5052        synchronized(this) {
5053            final long origId = Binder.clearCallingIdentity();
5054            try {
5055                ProcessRecord app = getRecordForAppLocked(appInt);
5056                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5057            } finally {
5058                Binder.restoreCallingIdentity(origId);
5059            }
5060        }
5061    }
5062
5063    @Override
5064    public boolean willActivityBeVisible(IBinder token) {
5065        synchronized(this) {
5066            ActivityStack stack = ActivityRecord.getStackLocked(token);
5067            if (stack != null) {
5068                return stack.willActivityBeVisibleLocked(token);
5069            }
5070            return false;
5071        }
5072    }
5073
5074    @Override
5075    public void overridePendingTransition(IBinder token, String packageName,
5076            int enterAnim, int exitAnim) {
5077        synchronized(this) {
5078            ActivityRecord self = ActivityRecord.isInStackLocked(token);
5079            if (self == null) {
5080                return;
5081            }
5082
5083            final long origId = Binder.clearCallingIdentity();
5084
5085            if (self.state == ActivityState.RESUMED
5086                    || self.state == ActivityState.PAUSING) {
5087                mWindowManager.overridePendingAppTransition(packageName,
5088                        enterAnim, exitAnim, null);
5089            }
5090
5091            Binder.restoreCallingIdentity(origId);
5092        }
5093    }
5094
5095    /**
5096     * Main function for removing an existing process from the activity manager
5097     * as a result of that process going away.  Clears out all connections
5098     * to the process.
5099     */
5100    private final void handleAppDiedLocked(ProcessRecord app,
5101            boolean restarting, boolean allowRestart) {
5102        int pid = app.pid;
5103        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5104                false /*replacingPid*/);
5105        if (!kept && !restarting) {
5106            removeLruProcessLocked(app);
5107            if (pid > 0) {
5108                ProcessList.remove(pid);
5109            }
5110        }
5111
5112        if (mProfileProc == app) {
5113            clearProfilerLocked();
5114        }
5115
5116        // Remove this application's activities from active lists.
5117        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5118
5119        app.activities.clear();
5120
5121        if (app.instr != null) {
5122            Slog.w(TAG, "Crash of app " + app.processName
5123                  + " running instrumentation " + app.instr.mClass);
5124            Bundle info = new Bundle();
5125            info.putString("shortMsg", "Process crashed.");
5126            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5127        }
5128
5129        mWindowManager.deferSurfaceLayout();
5130        try {
5131            if (!restarting && hasVisibleActivities
5132                    && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5133                // If there was nothing to resume, and we are not already restarting this process, but
5134                // there is a visible activity that is hosted by the process...  then make sure all
5135                // visible activities are running, taking care of restarting this process.
5136                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5137            }
5138        } finally {
5139            mWindowManager.continueSurfaceLayout();
5140        }
5141    }
5142
5143    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5144        IBinder threadBinder = thread.asBinder();
5145        // Find the application record.
5146        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5147            ProcessRecord rec = mLruProcesses.get(i);
5148            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5149                return i;
5150            }
5151        }
5152        return -1;
5153    }
5154
5155    final ProcessRecord getRecordForAppLocked(
5156            IApplicationThread thread) {
5157        if (thread == null) {
5158            return null;
5159        }
5160
5161        int appIndex = getLRURecordIndexForAppLocked(thread);
5162        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5163    }
5164
5165    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5166        // If there are no longer any background processes running,
5167        // and the app that died was not running instrumentation,
5168        // then tell everyone we are now low on memory.
5169        boolean haveBg = false;
5170        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5171            ProcessRecord rec = mLruProcesses.get(i);
5172            if (rec.thread != null
5173                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5174                haveBg = true;
5175                break;
5176            }
5177        }
5178
5179        if (!haveBg) {
5180            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5181            if (doReport) {
5182                long now = SystemClock.uptimeMillis();
5183                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5184                    doReport = false;
5185                } else {
5186                    mLastMemUsageReportTime = now;
5187                }
5188            }
5189            final ArrayList<ProcessMemInfo> memInfos
5190                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5191            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5192            long now = SystemClock.uptimeMillis();
5193            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5194                ProcessRecord rec = mLruProcesses.get(i);
5195                if (rec == dyingProc || rec.thread == null) {
5196                    continue;
5197                }
5198                if (doReport) {
5199                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5200                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5201                }
5202                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5203                    // The low memory report is overriding any current
5204                    // state for a GC request.  Make sure to do
5205                    // heavy/important/visible/foreground processes first.
5206                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5207                        rec.lastRequestedGc = 0;
5208                    } else {
5209                        rec.lastRequestedGc = rec.lastLowMemory;
5210                    }
5211                    rec.reportLowMemory = true;
5212                    rec.lastLowMemory = now;
5213                    mProcessesToGc.remove(rec);
5214                    addProcessToGcListLocked(rec);
5215                }
5216            }
5217            if (doReport) {
5218                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5219                mHandler.sendMessage(msg);
5220            }
5221            scheduleAppGcsLocked();
5222        }
5223    }
5224
5225    final void appDiedLocked(ProcessRecord app) {
5226       appDiedLocked(app, app.pid, app.thread, false);
5227    }
5228
5229    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5230            boolean fromBinderDied) {
5231        // First check if this ProcessRecord is actually active for the pid.
5232        synchronized (mPidsSelfLocked) {
5233            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5234            if (curProc != app) {
5235                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5236                return;
5237            }
5238        }
5239
5240        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5241        synchronized (stats) {
5242            stats.noteProcessDiedLocked(app.info.uid, pid);
5243        }
5244
5245        if (!app.killed) {
5246            if (!fromBinderDied) {
5247                Process.killProcessQuiet(pid);
5248            }
5249            killProcessGroup(app.uid, pid);
5250            app.killed = true;
5251        }
5252
5253        // Clean up already done if the process has been re-started.
5254        if (app.pid == pid && app.thread != null &&
5255                app.thread.asBinder() == thread.asBinder()) {
5256            boolean doLowMem = app.instr == null;
5257            boolean doOomAdj = doLowMem;
5258            if (!app.killedByAm) {
5259                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5260                        + ") has died");
5261                mAllowLowerMemLevel = true;
5262            } else {
5263                // Note that we always want to do oom adj to update our state with the
5264                // new number of procs.
5265                mAllowLowerMemLevel = false;
5266                doLowMem = false;
5267            }
5268            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5269            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5270                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5271            handleAppDiedLocked(app, false, true);
5272
5273            if (doOomAdj) {
5274                updateOomAdjLocked();
5275            }
5276            if (doLowMem) {
5277                doLowMemReportIfNeededLocked(app);
5278            }
5279        } else if (app.pid != pid) {
5280            // A new process has already been started.
5281            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5282                    + ") has died and restarted (pid " + app.pid + ").");
5283            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5284        } else if (DEBUG_PROCESSES) {
5285            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5286                    + thread.asBinder());
5287        }
5288    }
5289
5290    /**
5291     * If a stack trace dump file is configured, dump process stack traces.
5292     * @param clearTraces causes the dump file to be erased prior to the new
5293     *    traces being written, if true; when false, the new traces will be
5294     *    appended to any existing file content.
5295     * @param firstPids of dalvik VM processes to dump stack traces for first
5296     * @param lastPids of dalvik VM processes to dump stack traces for last
5297     * @param nativeProcs optional list of native process names to dump stack crawls
5298     * @return file containing stack traces, or null if no dump file is configured
5299     */
5300    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5301            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5302        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5303        if (tracesPath == null || tracesPath.length() == 0) {
5304            return null;
5305        }
5306
5307        File tracesFile = new File(tracesPath);
5308        try {
5309            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5310            tracesFile.createNewFile();
5311            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5312        } catch (IOException e) {
5313            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5314            return null;
5315        }
5316
5317        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5318        return tracesFile;
5319    }
5320
5321    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5322            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5323        // Use a FileObserver to detect when traces finish writing.
5324        // The order of traces is considered important to maintain for legibility.
5325        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5326            @Override
5327            public synchronized void onEvent(int event, String path) { notify(); }
5328        };
5329
5330        try {
5331            observer.startWatching();
5332
5333            // First collect all of the stacks of the most important pids.
5334            if (firstPids != null) {
5335                try {
5336                    int num = firstPids.size();
5337                    for (int i = 0; i < num; i++) {
5338                        synchronized (observer) {
5339                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5340                                    + firstPids.get(i));
5341                            final long sime = SystemClock.elapsedRealtime();
5342                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5343                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5344                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5345                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5346                        }
5347                    }
5348                } catch (InterruptedException e) {
5349                    Slog.wtf(TAG, e);
5350                }
5351            }
5352
5353            // Next collect the stacks of the native pids
5354            if (nativeProcs != null) {
5355                int[] pids = Process.getPidsForCommands(nativeProcs);
5356                if (pids != null) {
5357                    for (int pid : pids) {
5358                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5359                        final long sime = SystemClock.elapsedRealtime();
5360
5361                        Debug.dumpNativeBacktraceToFileTimeout(pid, tracesPath, 10);
5362                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5363                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5364                    }
5365                }
5366            }
5367
5368            // Lastly, measure CPU usage.
5369            if (processCpuTracker != null) {
5370                processCpuTracker.init();
5371                System.gc();
5372                processCpuTracker.update();
5373                try {
5374                    synchronized (processCpuTracker) {
5375                        processCpuTracker.wait(500); // measure over 1/2 second.
5376                    }
5377                } catch (InterruptedException e) {
5378                }
5379                processCpuTracker.update();
5380
5381                // We'll take the stack crawls of just the top apps using CPU.
5382                final int N = processCpuTracker.countWorkingStats();
5383                int numProcs = 0;
5384                for (int i=0; i<N && numProcs<5; i++) {
5385                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5386                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5387                        numProcs++;
5388                        try {
5389                            synchronized (observer) {
5390                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5391                                        + stats.pid);
5392                                final long stime = SystemClock.elapsedRealtime();
5393                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5394                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5395                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5396                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5397                            }
5398                        } catch (InterruptedException e) {
5399                            Slog.wtf(TAG, e);
5400                        }
5401                    } else if (DEBUG_ANR) {
5402                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5403                                + stats.pid);
5404                    }
5405                }
5406            }
5407        } finally {
5408            observer.stopWatching();
5409        }
5410    }
5411
5412    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5413        if (true || IS_USER_BUILD) {
5414            return;
5415        }
5416        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5417        if (tracesPath == null || tracesPath.length() == 0) {
5418            return;
5419        }
5420
5421        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5422        StrictMode.allowThreadDiskWrites();
5423        try {
5424            final File tracesFile = new File(tracesPath);
5425            final File tracesDir = tracesFile.getParentFile();
5426            final File tracesTmp = new File(tracesDir, "__tmp__");
5427            try {
5428                if (tracesFile.exists()) {
5429                    tracesTmp.delete();
5430                    tracesFile.renameTo(tracesTmp);
5431                }
5432                StringBuilder sb = new StringBuilder();
5433                Time tobj = new Time();
5434                tobj.set(System.currentTimeMillis());
5435                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5436                sb.append(": ");
5437                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5438                sb.append(" since ");
5439                sb.append(msg);
5440                FileOutputStream fos = new FileOutputStream(tracesFile);
5441                fos.write(sb.toString().getBytes());
5442                if (app == null) {
5443                    fos.write("\n*** No application process!".getBytes());
5444                }
5445                fos.close();
5446                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5447            } catch (IOException e) {
5448                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5449                return;
5450            }
5451
5452            if (app != null) {
5453                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5454                firstPids.add(app.pid);
5455                dumpStackTraces(tracesPath, firstPids, null, null, null);
5456            }
5457
5458            File lastTracesFile = null;
5459            File curTracesFile = null;
5460            for (int i=9; i>=0; i--) {
5461                String name = String.format(Locale.US, "slow%02d.txt", i);
5462                curTracesFile = new File(tracesDir, name);
5463                if (curTracesFile.exists()) {
5464                    if (lastTracesFile != null) {
5465                        curTracesFile.renameTo(lastTracesFile);
5466                    } else {
5467                        curTracesFile.delete();
5468                    }
5469                }
5470                lastTracesFile = curTracesFile;
5471            }
5472            tracesFile.renameTo(curTracesFile);
5473            if (tracesTmp.exists()) {
5474                tracesTmp.renameTo(tracesFile);
5475            }
5476        } finally {
5477            StrictMode.setThreadPolicy(oldPolicy);
5478        }
5479    }
5480
5481    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5482        if (!mLaunchWarningShown) {
5483            mLaunchWarningShown = true;
5484            mUiHandler.post(new Runnable() {
5485                @Override
5486                public void run() {
5487                    synchronized (ActivityManagerService.this) {
5488                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5489                        d.show();
5490                        mUiHandler.postDelayed(new Runnable() {
5491                            @Override
5492                            public void run() {
5493                                synchronized (ActivityManagerService.this) {
5494                                    d.dismiss();
5495                                    mLaunchWarningShown = false;
5496                                }
5497                            }
5498                        }, 4000);
5499                    }
5500                }
5501            });
5502        }
5503    }
5504
5505    @Override
5506    public boolean clearApplicationUserData(final String packageName,
5507            final IPackageDataObserver observer, int userId) {
5508        enforceNotIsolatedCaller("clearApplicationUserData");
5509        int uid = Binder.getCallingUid();
5510        int pid = Binder.getCallingPid();
5511        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5512                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5513
5514
5515        long callingId = Binder.clearCallingIdentity();
5516        try {
5517            IPackageManager pm = AppGlobals.getPackageManager();
5518            int pkgUid = -1;
5519            synchronized(this) {
5520                if (getPackageManagerInternalLocked().isPackageDataProtected(
5521                        userId, packageName)) {
5522                    throw new SecurityException(
5523                            "Cannot clear data for a protected package: " + packageName);
5524                }
5525
5526                try {
5527                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5528                } catch (RemoteException e) {
5529                }
5530                if (pkgUid == -1) {
5531                    Slog.w(TAG, "Invalid packageName: " + packageName);
5532                    if (observer != null) {
5533                        try {
5534                            observer.onRemoveCompleted(packageName, false);
5535                        } catch (RemoteException e) {
5536                            Slog.i(TAG, "Observer no longer exists.");
5537                        }
5538                    }
5539                    return false;
5540                }
5541                if (uid == pkgUid || checkComponentPermission(
5542                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5543                        pid, uid, -1, true)
5544                        == PackageManager.PERMISSION_GRANTED) {
5545                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5546                } else {
5547                    throw new SecurityException("PID " + pid + " does not have permission "
5548                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5549                                    + " of package " + packageName);
5550                }
5551
5552                // Remove all tasks match the cleared application package and user
5553                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5554                    final TaskRecord tr = mRecentTasks.get(i);
5555                    final String taskPackageName =
5556                            tr.getBaseIntent().getComponent().getPackageName();
5557                    if (tr.userId != userId) continue;
5558                    if (!taskPackageName.equals(packageName)) continue;
5559                    mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5560                }
5561            }
5562
5563            final int pkgUidF = pkgUid;
5564            final int userIdF = userId;
5565            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5566                @Override
5567                public void onRemoveCompleted(String packageName, boolean succeeded)
5568                        throws RemoteException {
5569                    synchronized (ActivityManagerService.this) {
5570                        finishForceStopPackageLocked(packageName, pkgUidF);
5571                    }
5572
5573                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5574                            Uri.fromParts("package", packageName, null));
5575                    intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
5576                    intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5577                    intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5578                    broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5579                            null, null, 0, null, null, null, null, false, false, userIdF);
5580
5581                    if (observer != null) {
5582                        observer.onRemoveCompleted(packageName, succeeded);
5583                    }
5584                }
5585            };
5586
5587            try {
5588                // Clear application user data
5589                pm.clearApplicationUserData(packageName, localObserver, userId);
5590
5591                synchronized(this) {
5592                    // Remove all permissions granted from/to this package
5593                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5594                }
5595
5596                // Reset notification settings.
5597                INotificationManager inm = NotificationManager.getService();
5598                inm.clearData(packageName, pkgUidF, uid == pkgUidF);
5599            } catch (RemoteException e) {
5600            }
5601        } finally {
5602            Binder.restoreCallingIdentity(callingId);
5603        }
5604        return true;
5605    }
5606
5607    @Override
5608    public void killBackgroundProcesses(final String packageName, int userId) {
5609        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5610                != PackageManager.PERMISSION_GRANTED &&
5611                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5612                        != PackageManager.PERMISSION_GRANTED) {
5613            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5614                    + Binder.getCallingPid()
5615                    + ", uid=" + Binder.getCallingUid()
5616                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5617            Slog.w(TAG, msg);
5618            throw new SecurityException(msg);
5619        }
5620
5621        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5622                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5623        long callingId = Binder.clearCallingIdentity();
5624        try {
5625            IPackageManager pm = AppGlobals.getPackageManager();
5626            synchronized(this) {
5627                int appId = -1;
5628                try {
5629                    appId = UserHandle.getAppId(
5630                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5631                } catch (RemoteException e) {
5632                }
5633                if (appId == -1) {
5634                    Slog.w(TAG, "Invalid packageName: " + packageName);
5635                    return;
5636                }
5637                killPackageProcessesLocked(packageName, appId, userId,
5638                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5639            }
5640        } finally {
5641            Binder.restoreCallingIdentity(callingId);
5642        }
5643    }
5644
5645    @Override
5646    public void killAllBackgroundProcesses() {
5647        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5648                != PackageManager.PERMISSION_GRANTED) {
5649            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5650                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5651                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5652            Slog.w(TAG, msg);
5653            throw new SecurityException(msg);
5654        }
5655
5656        final long callingId = Binder.clearCallingIdentity();
5657        try {
5658            synchronized (this) {
5659                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5660                final int NP = mProcessNames.getMap().size();
5661                for (int ip = 0; ip < NP; ip++) {
5662                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5663                    final int NA = apps.size();
5664                    for (int ia = 0; ia < NA; ia++) {
5665                        final ProcessRecord app = apps.valueAt(ia);
5666                        if (app.persistent) {
5667                            // We don't kill persistent processes.
5668                            continue;
5669                        }
5670                        if (app.removed) {
5671                            procs.add(app);
5672                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5673                            app.removed = true;
5674                            procs.add(app);
5675                        }
5676                    }
5677                }
5678
5679                final int N = procs.size();
5680                for (int i = 0; i < N; i++) {
5681                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5682                }
5683
5684                mAllowLowerMemLevel = true;
5685
5686                updateOomAdjLocked();
5687                doLowMemReportIfNeededLocked(null);
5688            }
5689        } finally {
5690            Binder.restoreCallingIdentity(callingId);
5691        }
5692    }
5693
5694    /**
5695     * Kills all background processes, except those matching any of the
5696     * specified properties.
5697     *
5698     * @param minTargetSdk the target SDK version at or above which to preserve
5699     *                     processes, or {@code -1} to ignore the target SDK
5700     * @param maxProcState the process state at or below which to preserve
5701     *                     processes, or {@code -1} to ignore the process state
5702     */
5703    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5704        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5705                != PackageManager.PERMISSION_GRANTED) {
5706            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5707                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5708                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5709            Slog.w(TAG, msg);
5710            throw new SecurityException(msg);
5711        }
5712
5713        final long callingId = Binder.clearCallingIdentity();
5714        try {
5715            synchronized (this) {
5716                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5717                final int NP = mProcessNames.getMap().size();
5718                for (int ip = 0; ip < NP; ip++) {
5719                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5720                    final int NA = apps.size();
5721                    for (int ia = 0; ia < NA; ia++) {
5722                        final ProcessRecord app = apps.valueAt(ia);
5723                        if (app.removed) {
5724                            procs.add(app);
5725                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5726                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5727                            app.removed = true;
5728                            procs.add(app);
5729                        }
5730                    }
5731                }
5732
5733                final int N = procs.size();
5734                for (int i = 0; i < N; i++) {
5735                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5736                }
5737            }
5738        } finally {
5739            Binder.restoreCallingIdentity(callingId);
5740        }
5741    }
5742
5743    @Override
5744    public void forceStopPackage(final String packageName, int userId) {
5745        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5746                != PackageManager.PERMISSION_GRANTED) {
5747            String msg = "Permission Denial: forceStopPackage() from pid="
5748                    + Binder.getCallingPid()
5749                    + ", uid=" + Binder.getCallingUid()
5750                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5751            Slog.w(TAG, msg);
5752            throw new SecurityException(msg);
5753        }
5754        final int callingPid = Binder.getCallingPid();
5755        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5756                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5757        long callingId = Binder.clearCallingIdentity();
5758        try {
5759            IPackageManager pm = AppGlobals.getPackageManager();
5760            synchronized(this) {
5761                int[] users = userId == UserHandle.USER_ALL
5762                        ? mUserController.getUsers() : new int[] { userId };
5763                for (int user : users) {
5764                    int pkgUid = -1;
5765                    try {
5766                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5767                                user);
5768                    } catch (RemoteException e) {
5769                    }
5770                    if (pkgUid == -1) {
5771                        Slog.w(TAG, "Invalid packageName: " + packageName);
5772                        continue;
5773                    }
5774                    try {
5775                        pm.setPackageStoppedState(packageName, true, user);
5776                    } catch (RemoteException e) {
5777                    } catch (IllegalArgumentException e) {
5778                        Slog.w(TAG, "Failed trying to unstop package "
5779                                + packageName + ": " + e);
5780                    }
5781                    if (mUserController.isUserRunningLocked(user, 0)) {
5782                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5783                        finishForceStopPackageLocked(packageName, pkgUid);
5784                    }
5785                }
5786            }
5787        } finally {
5788            Binder.restoreCallingIdentity(callingId);
5789        }
5790    }
5791
5792    @Override
5793    public void addPackageDependency(String packageName) {
5794        synchronized (this) {
5795            int callingPid = Binder.getCallingPid();
5796            if (callingPid == Process.myPid()) {
5797                //  Yeah, um, no.
5798                return;
5799            }
5800            ProcessRecord proc;
5801            synchronized (mPidsSelfLocked) {
5802                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5803            }
5804            if (proc != null) {
5805                if (proc.pkgDeps == null) {
5806                    proc.pkgDeps = new ArraySet<String>(1);
5807                }
5808                proc.pkgDeps.add(packageName);
5809            }
5810        }
5811    }
5812
5813    /*
5814     * The pkg name and app id have to be specified.
5815     */
5816    @Override
5817    public void killApplication(String pkg, int appId, int userId, String reason) {
5818        if (pkg == null) {
5819            return;
5820        }
5821        // Make sure the uid is valid.
5822        if (appId < 0) {
5823            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5824            return;
5825        }
5826        int callerUid = Binder.getCallingUid();
5827        // Only the system server can kill an application
5828        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5829            // Post an aysnc message to kill the application
5830            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5831            msg.arg1 = appId;
5832            msg.arg2 = userId;
5833            Bundle bundle = new Bundle();
5834            bundle.putString("pkg", pkg);
5835            bundle.putString("reason", reason);
5836            msg.obj = bundle;
5837            mHandler.sendMessage(msg);
5838        } else {
5839            throw new SecurityException(callerUid + " cannot kill pkg: " +
5840                    pkg);
5841        }
5842    }
5843
5844    @Override
5845    public void closeSystemDialogs(String reason) {
5846        enforceNotIsolatedCaller("closeSystemDialogs");
5847
5848        final int pid = Binder.getCallingPid();
5849        final int uid = Binder.getCallingUid();
5850        final long origId = Binder.clearCallingIdentity();
5851        try {
5852            synchronized (this) {
5853                // Only allow this from foreground processes, so that background
5854                // applications can't abuse it to prevent system UI from being shown.
5855                if (uid >= Process.FIRST_APPLICATION_UID) {
5856                    ProcessRecord proc;
5857                    synchronized (mPidsSelfLocked) {
5858                        proc = mPidsSelfLocked.get(pid);
5859                    }
5860                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5861                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5862                                + " from background process " + proc);
5863                        return;
5864                    }
5865                }
5866                closeSystemDialogsLocked(reason);
5867            }
5868        } finally {
5869            Binder.restoreCallingIdentity(origId);
5870        }
5871    }
5872
5873    void closeSystemDialogsLocked(String reason) {
5874        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5875        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5876                | Intent.FLAG_RECEIVER_FOREGROUND);
5877        if (reason != null) {
5878            intent.putExtra("reason", reason);
5879        }
5880        mWindowManager.closeSystemDialogs(reason);
5881
5882        mStackSupervisor.closeSystemDialogsLocked();
5883
5884        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5885                AppOpsManager.OP_NONE, null, false, false,
5886                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5887    }
5888
5889    @Override
5890    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5891        enforceNotIsolatedCaller("getProcessMemoryInfo");
5892        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5893        for (int i=pids.length-1; i>=0; i--) {
5894            ProcessRecord proc;
5895            int oomAdj;
5896            synchronized (this) {
5897                synchronized (mPidsSelfLocked) {
5898                    proc = mPidsSelfLocked.get(pids[i]);
5899                    oomAdj = proc != null ? proc.setAdj : 0;
5900                }
5901            }
5902            infos[i] = new Debug.MemoryInfo();
5903            Debug.getMemoryInfo(pids[i], infos[i]);
5904            if (proc != null) {
5905                synchronized (this) {
5906                    if (proc.thread != null && proc.setAdj == oomAdj) {
5907                        // Record this for posterity if the process has been stable.
5908                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5909                                infos[i].getTotalUss(), false, proc.pkgList);
5910                    }
5911                }
5912            }
5913        }
5914        return infos;
5915    }
5916
5917    @Override
5918    public long[] getProcessPss(int[] pids) {
5919        enforceNotIsolatedCaller("getProcessPss");
5920        long[] pss = new long[pids.length];
5921        for (int i=pids.length-1; i>=0; i--) {
5922            ProcessRecord proc;
5923            int oomAdj;
5924            synchronized (this) {
5925                synchronized (mPidsSelfLocked) {
5926                    proc = mPidsSelfLocked.get(pids[i]);
5927                    oomAdj = proc != null ? proc.setAdj : 0;
5928                }
5929            }
5930            long[] tmpUss = new long[1];
5931            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5932            if (proc != null) {
5933                synchronized (this) {
5934                    if (proc.thread != null && proc.setAdj == oomAdj) {
5935                        // Record this for posterity if the process has been stable.
5936                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5937                    }
5938                }
5939            }
5940        }
5941        return pss;
5942    }
5943
5944    @Override
5945    public void killApplicationProcess(String processName, int uid) {
5946        if (processName == null) {
5947            return;
5948        }
5949
5950        int callerUid = Binder.getCallingUid();
5951        // Only the system server can kill an application
5952        if (callerUid == Process.SYSTEM_UID) {
5953            synchronized (this) {
5954                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5955                if (app != null && app.thread != null) {
5956                    try {
5957                        app.thread.scheduleSuicide();
5958                    } catch (RemoteException e) {
5959                        // If the other end already died, then our work here is done.
5960                    }
5961                } else {
5962                    Slog.w(TAG, "Process/uid not found attempting kill of "
5963                            + processName + " / " + uid);
5964                }
5965            }
5966        } else {
5967            throw new SecurityException(callerUid + " cannot kill app process: " +
5968                    processName);
5969        }
5970    }
5971
5972    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5973        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5974                false, true, false, false, UserHandle.getUserId(uid), reason);
5975    }
5976
5977    private void finishForceStopPackageLocked(final String packageName, int uid) {
5978        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5979                Uri.fromParts("package", packageName, null));
5980        if (!mProcessesReady) {
5981            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5982                    | Intent.FLAG_RECEIVER_FOREGROUND);
5983        }
5984        intent.putExtra(Intent.EXTRA_UID, uid);
5985        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5986        broadcastIntentLocked(null, null, intent,
5987                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5988                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5989    }
5990
5991
5992    private final boolean killPackageProcessesLocked(String packageName, int appId,
5993            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5994            boolean doit, boolean evenPersistent, String reason) {
5995        ArrayList<ProcessRecord> procs = new ArrayList<>();
5996
5997        // Remove all processes this package may have touched: all with the
5998        // same UID (except for the system or root user), and all whose name
5999        // matches the package name.
6000        final int NP = mProcessNames.getMap().size();
6001        for (int ip=0; ip<NP; ip++) {
6002            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6003            final int NA = apps.size();
6004            for (int ia=0; ia<NA; ia++) {
6005                ProcessRecord app = apps.valueAt(ia);
6006                if (app.persistent && !evenPersistent) {
6007                    // we don't kill persistent processes
6008                    continue;
6009                }
6010                if (app.removed) {
6011                    if (doit) {
6012                        procs.add(app);
6013                    }
6014                    continue;
6015                }
6016
6017                // Skip process if it doesn't meet our oom adj requirement.
6018                if (app.setAdj < minOomAdj) {
6019                    continue;
6020                }
6021
6022                // If no package is specified, we call all processes under the
6023                // give user id.
6024                if (packageName == null) {
6025                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
6026                        continue;
6027                    }
6028                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6029                        continue;
6030                    }
6031                // Package has been specified, we want to hit all processes
6032                // that match it.  We need to qualify this by the processes
6033                // that are running under the specified app and user ID.
6034                } else {
6035                    final boolean isDep = app.pkgDeps != null
6036                            && app.pkgDeps.contains(packageName);
6037                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6038                        continue;
6039                    }
6040                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
6041                        continue;
6042                    }
6043                    if (!app.pkgList.containsKey(packageName) && !isDep) {
6044                        continue;
6045                    }
6046                }
6047
6048                // Process has passed all conditions, kill it!
6049                if (!doit) {
6050                    return true;
6051                }
6052                app.removed = true;
6053                procs.add(app);
6054            }
6055        }
6056
6057        int N = procs.size();
6058        for (int i=0; i<N; i++) {
6059            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6060        }
6061        updateOomAdjLocked();
6062        return N > 0;
6063    }
6064
6065    private void cleanupDisabledPackageComponentsLocked(
6066            String packageName, int userId, boolean killProcess, String[] changedClasses) {
6067
6068        Set<String> disabledClasses = null;
6069        boolean packageDisabled = false;
6070        IPackageManager pm = AppGlobals.getPackageManager();
6071
6072        if (changedClasses == null) {
6073            // Nothing changed...
6074            return;
6075        }
6076
6077        // Determine enable/disable state of the package and its components.
6078        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6079        for (int i = changedClasses.length - 1; i >= 0; i--) {
6080            final String changedClass = changedClasses[i];
6081
6082            if (changedClass.equals(packageName)) {
6083                try {
6084                    // Entire package setting changed
6085                    enabled = pm.getApplicationEnabledSetting(packageName,
6086                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6087                } catch (Exception e) {
6088                    // No such package/component; probably racing with uninstall.  In any
6089                    // event it means we have nothing further to do here.
6090                    return;
6091                }
6092                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6093                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6094                if (packageDisabled) {
6095                    // Entire package is disabled.
6096                    // No need to continue to check component states.
6097                    disabledClasses = null;
6098                    break;
6099                }
6100            } else {
6101                try {
6102                    enabled = pm.getComponentEnabledSetting(
6103                            new ComponentName(packageName, changedClass),
6104                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6105                } catch (Exception e) {
6106                    // As above, probably racing with uninstall.
6107                    return;
6108                }
6109                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6110                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6111                    if (disabledClasses == null) {
6112                        disabledClasses = new ArraySet<>(changedClasses.length);
6113                    }
6114                    disabledClasses.add(changedClass);
6115                }
6116            }
6117        }
6118
6119        if (!packageDisabled && disabledClasses == null) {
6120            // Nothing to do here...
6121            return;
6122        }
6123
6124        // Clean-up disabled activities.
6125        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6126                packageName, disabledClasses, true, false, userId) && mBooted) {
6127            mStackSupervisor.resumeFocusedStackTopActivityLocked();
6128            mStackSupervisor.scheduleIdleLocked();
6129        }
6130
6131        // Clean-up disabled tasks
6132        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6133
6134        // Clean-up disabled services.
6135        mServices.bringDownDisabledPackageServicesLocked(
6136                packageName, disabledClasses, userId, false, killProcess, true);
6137
6138        // Clean-up disabled providers.
6139        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6140        mProviderMap.collectPackageProvidersLocked(
6141                packageName, disabledClasses, true, false, userId, providers);
6142        for (int i = providers.size() - 1; i >= 0; i--) {
6143            removeDyingProviderLocked(null, providers.get(i), true);
6144        }
6145
6146        // Clean-up disabled broadcast receivers.
6147        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6148            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6149                    packageName, disabledClasses, userId, true);
6150        }
6151
6152    }
6153
6154    final boolean clearBroadcastQueueForUserLocked(int userId) {
6155        boolean didSomething = false;
6156        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6157            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6158                    null, null, userId, true);
6159        }
6160        return didSomething;
6161    }
6162
6163    final boolean forceStopPackageLocked(String packageName, int appId,
6164            boolean callerWillRestart, boolean purgeCache, boolean doit,
6165            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6166        int i;
6167
6168        if (userId == UserHandle.USER_ALL && packageName == null) {
6169            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6170        }
6171
6172        if (appId < 0 && packageName != null) {
6173            try {
6174                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6175                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6176            } catch (RemoteException e) {
6177            }
6178        }
6179
6180        if (doit) {
6181            if (packageName != null) {
6182                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6183                        + " user=" + userId + ": " + reason);
6184            } else {
6185                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6186            }
6187
6188            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6189        }
6190
6191        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6192                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6193                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6194
6195        didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName);
6196
6197        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6198                packageName, null, doit, evenPersistent, userId)) {
6199            if (!doit) {
6200                return true;
6201            }
6202            didSomething = true;
6203        }
6204
6205        if (mServices.bringDownDisabledPackageServicesLocked(
6206                packageName, null, userId, evenPersistent, true, doit)) {
6207            if (!doit) {
6208                return true;
6209            }
6210            didSomething = true;
6211        }
6212
6213        if (packageName == null) {
6214            // Remove all sticky broadcasts from this user.
6215            mStickyBroadcasts.remove(userId);
6216        }
6217
6218        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6219        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6220                userId, providers)) {
6221            if (!doit) {
6222                return true;
6223            }
6224            didSomething = true;
6225        }
6226        for (i = providers.size() - 1; i >= 0; i--) {
6227            removeDyingProviderLocked(null, providers.get(i), true);
6228        }
6229
6230        // Remove transient permissions granted from/to this package/user
6231        removeUriPermissionsForPackageLocked(packageName, userId, false);
6232
6233        if (doit) {
6234            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6235                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6236                        packageName, null, userId, doit);
6237            }
6238        }
6239
6240        if (packageName == null || uninstalling) {
6241            // Remove pending intents.  For now we only do this when force
6242            // stopping users, because we have some problems when doing this
6243            // for packages -- app widgets are not currently cleaned up for
6244            // such packages, so they can be left with bad pending intents.
6245            if (mIntentSenderRecords.size() > 0) {
6246                Iterator<WeakReference<PendingIntentRecord>> it
6247                        = mIntentSenderRecords.values().iterator();
6248                while (it.hasNext()) {
6249                    WeakReference<PendingIntentRecord> wpir = it.next();
6250                    if (wpir == null) {
6251                        it.remove();
6252                        continue;
6253                    }
6254                    PendingIntentRecord pir = wpir.get();
6255                    if (pir == null) {
6256                        it.remove();
6257                        continue;
6258                    }
6259                    if (packageName == null) {
6260                        // Stopping user, remove all objects for the user.
6261                        if (pir.key.userId != userId) {
6262                            // Not the same user, skip it.
6263                            continue;
6264                        }
6265                    } else {
6266                        if (UserHandle.getAppId(pir.uid) != appId) {
6267                            // Different app id, skip it.
6268                            continue;
6269                        }
6270                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6271                            // Different user, skip it.
6272                            continue;
6273                        }
6274                        if (!pir.key.packageName.equals(packageName)) {
6275                            // Different package, skip it.
6276                            continue;
6277                        }
6278                    }
6279                    if (!doit) {
6280                        return true;
6281                    }
6282                    didSomething = true;
6283                    it.remove();
6284                    pir.canceled = true;
6285                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6286                        pir.key.activity.pendingResults.remove(pir.ref);
6287                    }
6288                }
6289            }
6290        }
6291
6292        if (doit) {
6293            if (purgeCache && packageName != null) {
6294                AttributeCache ac = AttributeCache.instance();
6295                if (ac != null) {
6296                    ac.removePackage(packageName);
6297                }
6298            }
6299            if (mBooted) {
6300                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6301                mStackSupervisor.scheduleIdleLocked();
6302            }
6303        }
6304
6305        return didSomething;
6306    }
6307
6308    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6309        return removeProcessNameLocked(name, uid, null);
6310    }
6311
6312    private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
6313            final ProcessRecord expecting) {
6314        ProcessRecord old = mProcessNames.get(name, uid);
6315        // Only actually remove when the currently recorded value matches the
6316        // record that we expected; if it doesn't match then we raced with a
6317        // newly created process and we don't want to destroy the new one.
6318        if ((expecting == null) || (old == expecting)) {
6319            mProcessNames.remove(name, uid);
6320        }
6321        if (old != null && old.uidRecord != null) {
6322            old.uidRecord.numProcs--;
6323            if (old.uidRecord.numProcs == 0) {
6324                // No more processes using this uid, tell clients it is gone.
6325                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6326                        "No more processes in " + old.uidRecord);
6327                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6328                mActiveUids.remove(uid);
6329                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6330            }
6331            old.uidRecord = null;
6332        }
6333        mIsolatedProcesses.remove(uid);
6334        return old;
6335    }
6336
6337    private final void addProcessNameLocked(ProcessRecord proc) {
6338        // We shouldn't already have a process under this name, but just in case we
6339        // need to clean up whatever may be there now.
6340        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6341        if (old == proc && proc.persistent) {
6342            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6343            Slog.w(TAG, "Re-adding persistent process " + proc);
6344        } else if (old != null) {
6345            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6346        }
6347        UidRecord uidRec = mActiveUids.get(proc.uid);
6348        if (uidRec == null) {
6349            uidRec = new UidRecord(proc.uid);
6350            // This is the first appearance of the uid, report it now!
6351            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6352                    "Creating new process uid: " + uidRec);
6353            if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0) {
6354                uidRec.setWhitelist = uidRec.curWhitelist = true;
6355            }
6356            mActiveUids.put(proc.uid, uidRec);
6357            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6358            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6359        }
6360        proc.uidRecord = uidRec;
6361
6362        // Reset render thread tid if it was already set, so new process can set it again.
6363        proc.renderThreadTid = 0;
6364        uidRec.numProcs++;
6365        mProcessNames.put(proc.processName, proc.uid, proc);
6366        if (proc.isolated) {
6367            mIsolatedProcesses.put(proc.uid, proc);
6368        }
6369    }
6370
6371    boolean removeProcessLocked(ProcessRecord app,
6372            boolean callerWillRestart, boolean allowRestart, String reason) {
6373        final String name = app.processName;
6374        final int uid = app.uid;
6375        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6376            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6377
6378        ProcessRecord old = mProcessNames.get(name, uid);
6379        if (old != app) {
6380            // This process is no longer active, so nothing to do.
6381            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6382            return false;
6383        }
6384        removeProcessNameLocked(name, uid);
6385        if (mHeavyWeightProcess == app) {
6386            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6387                    mHeavyWeightProcess.userId, 0));
6388            mHeavyWeightProcess = null;
6389        }
6390        boolean needRestart = false;
6391        if (app.pid > 0 && app.pid != MY_PID) {
6392            int pid = app.pid;
6393            synchronized (mPidsSelfLocked) {
6394                mPidsSelfLocked.remove(pid);
6395                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6396            }
6397            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6398            if (app.isolated) {
6399                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6400            }
6401            boolean willRestart = false;
6402            if (app.persistent && !app.isolated) {
6403                if (!callerWillRestart) {
6404                    willRestart = true;
6405                } else {
6406                    needRestart = true;
6407                }
6408            }
6409            app.kill(reason, true);
6410            handleAppDiedLocked(app, willRestart, allowRestart);
6411            if (willRestart) {
6412                removeLruProcessLocked(app);
6413                addAppLocked(app.info, null, false, null /* ABI override */);
6414            }
6415        } else {
6416            mRemovedProcesses.add(app);
6417        }
6418
6419        return needRestart;
6420    }
6421
6422    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6423        cleanupAppInLaunchingProvidersLocked(app, true);
6424        removeProcessLocked(app, false, true, "timeout publishing content providers");
6425    }
6426
6427    private final void processStartTimedOutLocked(ProcessRecord app) {
6428        final int pid = app.pid;
6429        boolean gone = false;
6430        synchronized (mPidsSelfLocked) {
6431            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6432            if (knownApp != null && knownApp.thread == null) {
6433                mPidsSelfLocked.remove(pid);
6434                gone = true;
6435            }
6436        }
6437
6438        if (gone) {
6439            Slog.w(TAG, "Process " + app + " failed to attach");
6440            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6441                    pid, app.uid, app.processName);
6442            removeProcessNameLocked(app.processName, app.uid);
6443            if (mHeavyWeightProcess == app) {
6444                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6445                        mHeavyWeightProcess.userId, 0));
6446                mHeavyWeightProcess = null;
6447            }
6448            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6449            if (app.isolated) {
6450                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6451            }
6452            // Take care of any launching providers waiting for this process.
6453            cleanupAppInLaunchingProvidersLocked(app, true);
6454            // Take care of any services that are waiting for the process.
6455            mServices.processStartTimedOutLocked(app);
6456            app.kill("start timeout", true);
6457            removeLruProcessLocked(app);
6458            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6459                Slog.w(TAG, "Unattached app died before backup, skipping");
6460                mHandler.post(new Runnable() {
6461                @Override
6462                    public void run(){
6463                        try {
6464                            IBackupManager bm = IBackupManager.Stub.asInterface(
6465                                    ServiceManager.getService(Context.BACKUP_SERVICE));
6466                            bm.agentDisconnected(app.info.packageName);
6467                        } catch (RemoteException e) {
6468                            // Can't happen; the backup manager is local
6469                        }
6470                    }
6471                });
6472            }
6473            if (isPendingBroadcastProcessLocked(pid)) {
6474                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6475                skipPendingBroadcastLocked(pid);
6476            }
6477        } else {
6478            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6479        }
6480    }
6481
6482    private final boolean attachApplicationLocked(IApplicationThread thread,
6483            int pid) {
6484
6485        // Find the application record that is being attached...  either via
6486        // the pid if we are running in multiple processes, or just pull the
6487        // next app record if we are emulating process with anonymous threads.
6488        ProcessRecord app;
6489        long startTime = SystemClock.uptimeMillis();
6490        if (pid != MY_PID && pid >= 0) {
6491            synchronized (mPidsSelfLocked) {
6492                app = mPidsSelfLocked.get(pid);
6493            }
6494        } else {
6495            app = null;
6496        }
6497
6498        if (app == null) {
6499            Slog.w(TAG, "No pending application record for pid " + pid
6500                    + " (IApplicationThread " + thread + "); dropping process");
6501            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6502            if (pid > 0 && pid != MY_PID) {
6503                Process.killProcessQuiet(pid);
6504                //TODO: killProcessGroup(app.info.uid, pid);
6505            } else {
6506                try {
6507                    thread.scheduleExit();
6508                } catch (Exception e) {
6509                    // Ignore exceptions.
6510                }
6511            }
6512            return false;
6513        }
6514
6515        // If this application record is still attached to a previous
6516        // process, clean it up now.
6517        if (app.thread != null) {
6518            handleAppDiedLocked(app, true, true);
6519        }
6520
6521        // Tell the process all about itself.
6522
6523        if (DEBUG_ALL) Slog.v(
6524                TAG, "Binding process pid " + pid + " to record " + app);
6525
6526        final String processName = app.processName;
6527        try {
6528            AppDeathRecipient adr = new AppDeathRecipient(
6529                    app, pid, thread);
6530            thread.asBinder().linkToDeath(adr, 0);
6531            app.deathRecipient = adr;
6532        } catch (RemoteException e) {
6533            app.resetPackageList(mProcessStats);
6534            startProcessLocked(app, "link fail", processName);
6535            return false;
6536        }
6537
6538        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6539
6540        app.makeActive(thread, mProcessStats);
6541        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6542        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6543        app.forcingToForeground = null;
6544        updateProcessForegroundLocked(app, false, false);
6545        app.hasShownUi = false;
6546        app.debugging = false;
6547        app.cached = false;
6548        app.killedByAm = false;
6549        app.killed = false;
6550
6551
6552        // We carefully use the same state that PackageManager uses for
6553        // filtering, since we use this flag to decide if we need to install
6554        // providers when user is unlocked later
6555        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6556
6557        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6558
6559        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6560        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6561
6562        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6563            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6564            msg.obj = app;
6565            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6566        }
6567
6568        checkTime(startTime, "attachApplicationLocked: before bindApplication");
6569
6570        if (!normalMode) {
6571            Slog.i(TAG, "Launching preboot mode app: " + app);
6572        }
6573
6574        if (DEBUG_ALL) Slog.v(
6575            TAG, "New app record " + app
6576            + " thread=" + thread.asBinder() + " pid=" + pid);
6577        try {
6578            int testMode = ApplicationThreadConstants.DEBUG_OFF;
6579            if (mDebugApp != null && mDebugApp.equals(processName)) {
6580                testMode = mWaitForDebugger
6581                    ? ApplicationThreadConstants.DEBUG_WAIT
6582                    : ApplicationThreadConstants.DEBUG_ON;
6583                app.debugging = true;
6584                if (mDebugTransient) {
6585                    mDebugApp = mOrigDebugApp;
6586                    mWaitForDebugger = mOrigWaitForDebugger;
6587                }
6588            }
6589            String profileFile = app.instr != null ? app.instr.mProfileFile : null;
6590            ParcelFileDescriptor profileFd = null;
6591            int samplingInterval = 0;
6592            boolean profileAutoStop = false;
6593            boolean profileStreamingOutput = false;
6594            if (mProfileApp != null && mProfileApp.equals(processName)) {
6595                mProfileProc = app;
6596                profileFile = mProfileFile;
6597                profileFd = mProfileFd;
6598                samplingInterval = mSamplingInterval;
6599                profileAutoStop = mAutoStopProfiler;
6600                profileStreamingOutput = mStreamingOutput;
6601            }
6602            boolean enableTrackAllocation = false;
6603            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6604                enableTrackAllocation = true;
6605                mTrackAllocationApp = null;
6606            }
6607
6608            // If the app is being launched for restore or full backup, set it up specially
6609            boolean isRestrictedBackupMode = false;
6610            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6611                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6612                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6613                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6614                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6615            }
6616
6617            if (app.instr != null) {
6618                notifyPackageUse(app.instr.mClass.getPackageName(),
6619                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6620            }
6621            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6622                    + processName + " with config " + getGlobalConfiguration());
6623            ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
6624            app.compat = compatibilityInfoForPackageLocked(appInfo);
6625            if (profileFd != null) {
6626                profileFd = profileFd.dup();
6627            }
6628            ProfilerInfo profilerInfo = profileFile == null ? null
6629                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop,
6630                                       profileStreamingOutput);
6631
6632            // We deprecated Build.SERIAL and only apps that target pre NMR1
6633            // SDK can see it. Since access to the serial is now behind a
6634            // permission we push down the value.
6635            String buildSerial = Build.UNKNOWN;
6636            // TODO: SHTOPSHIP Uncomment the check when clients migrate
6637//            if (appInfo.targetSdkVersion <= Build.VERSION_CODES.N_MR1) {
6638                buildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
6639                        ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
6640                        .getSerial();
6641//            }
6642
6643            // Check if this is a secondary process that should be incorporated into some
6644            // currently active instrumentation.  (Note we do this AFTER all of the profiling
6645            // stuff above because profiling can currently happen only in the primary
6646            // instrumentation process.)
6647            if (mActiveInstrumentation.size() > 0 && app.instr == null) {
6648                for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
6649                    ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
6650                    if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
6651                        if (aInstr.mTargetProcesses.length == 0) {
6652                            // This is the wildcard mode, where every process brought up for
6653                            // the target instrumentation should be included.
6654                            if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
6655                                app.instr = aInstr;
6656                                aInstr.mRunningProcesses.add(app);
6657                            }
6658                        } else {
6659                            for (String proc : aInstr.mTargetProcesses) {
6660                                if (proc.equals(app.processName)) {
6661                                    app.instr = aInstr;
6662                                    aInstr.mRunningProcesses.add(app);
6663                                    break;
6664                                }
6665                            }
6666                        }
6667                    }
6668                }
6669            }
6670
6671            checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
6672            if (app.instr != null) {
6673                thread.bindApplication(processName, appInfo, providers,
6674                        app.instr.mClass,
6675                        profilerInfo, app.instr.mArguments,
6676                        app.instr.mWatcher,
6677                        app.instr.mUiAutomationConnection, testMode,
6678                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
6679                        isRestrictedBackupMode || !normalMode, app.persistent,
6680                        new Configuration(getGlobalConfiguration()), app.compat,
6681                        getCommonServicesLocked(app.isolated),
6682                        mCoreSettingsObserver.getCoreSettingsLocked(),
6683                        buildSerial);
6684            } else {
6685                thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
6686                        null, null, null, testMode,
6687                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
6688                        isRestrictedBackupMode || !normalMode, app.persistent,
6689                        new Configuration(getGlobalConfiguration()), app.compat,
6690                        getCommonServicesLocked(app.isolated),
6691                        mCoreSettingsObserver.getCoreSettingsLocked(),
6692                        buildSerial);
6693            }
6694
6695            checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
6696            updateLruProcessLocked(app, false, null);
6697            checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
6698            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6699        } catch (Exception e) {
6700            // todo: Yikes!  What should we do?  For now we will try to
6701            // start another process, but that could easily get us in
6702            // an infinite loop of restarting processes...
6703            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6704
6705            app.resetPackageList(mProcessStats);
6706            app.unlinkDeathRecipient();
6707            startProcessLocked(app, "bind fail", processName);
6708            return false;
6709        }
6710
6711        // Remove this record from the list of starting applications.
6712        mPersistentStartingProcesses.remove(app);
6713        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6714                "Attach application locked removing on hold: " + app);
6715        mProcessesOnHold.remove(app);
6716
6717        boolean badApp = false;
6718        boolean didSomething = false;
6719
6720        // See if the top visible activity is waiting to run in this process...
6721        if (normalMode) {
6722            try {
6723                if (mStackSupervisor.attachApplicationLocked(app)) {
6724                    didSomething = true;
6725                }
6726            } catch (Exception e) {
6727                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6728                badApp = true;
6729            }
6730        }
6731
6732        // Find any services that should be running in this process...
6733        if (!badApp) {
6734            try {
6735                didSomething |= mServices.attachApplicationLocked(app, processName);
6736                checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
6737            } catch (Exception e) {
6738                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6739                badApp = true;
6740            }
6741        }
6742
6743        // Check if a next-broadcast receiver is in this process...
6744        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6745            try {
6746                didSomething |= sendPendingBroadcastsLocked(app);
6747                checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
6748            } catch (Exception e) {
6749                // If the app died trying to launch the receiver we declare it 'bad'
6750                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6751                badApp = true;
6752            }
6753        }
6754
6755        // Check whether the next backup agent is in this process...
6756        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6757            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6758                    "New app is backup target, launching agent for " + app);
6759            notifyPackageUse(mBackupTarget.appInfo.packageName,
6760                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6761            try {
6762                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6763                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6764                        mBackupTarget.backupMode);
6765            } catch (Exception e) {
6766                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6767                badApp = true;
6768            }
6769        }
6770
6771        if (badApp) {
6772            app.kill("error during init", true);
6773            handleAppDiedLocked(app, false, true);
6774            return false;
6775        }
6776
6777        if (!didSomething) {
6778            updateOomAdjLocked();
6779            checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
6780        }
6781
6782        return true;
6783    }
6784
6785    @Override
6786    public final void attachApplication(IApplicationThread thread) {
6787        synchronized (this) {
6788            int callingPid = Binder.getCallingPid();
6789            final long origId = Binder.clearCallingIdentity();
6790            attachApplicationLocked(thread, callingPid);
6791            Binder.restoreCallingIdentity(origId);
6792        }
6793    }
6794
6795    @Override
6796    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6797        final long origId = Binder.clearCallingIdentity();
6798        synchronized (this) {
6799            ActivityStack stack = ActivityRecord.getStackLocked(token);
6800            if (stack != null) {
6801                ActivityRecord r =
6802                        mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
6803                                false /* processPausingActivities */, config);
6804                if (stopProfiling) {
6805                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6806                        try {
6807                            mProfileFd.close();
6808                        } catch (IOException e) {
6809                        }
6810                        clearProfilerLocked();
6811                    }
6812                }
6813            }
6814        }
6815        Binder.restoreCallingIdentity(origId);
6816    }
6817
6818    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6819        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6820                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6821    }
6822
6823    void enableScreenAfterBoot() {
6824        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6825                SystemClock.uptimeMillis());
6826        mWindowManager.enableScreenAfterBoot();
6827
6828        synchronized (this) {
6829            updateEventDispatchingLocked();
6830        }
6831    }
6832
6833    @Override
6834    public void showBootMessage(final CharSequence msg, final boolean always) {
6835        if (Binder.getCallingUid() != Process.myUid()) {
6836            throw new SecurityException();
6837        }
6838        mWindowManager.showBootMessage(msg, always);
6839    }
6840
6841    @Override
6842    public void keyguardGoingAway(int flags) {
6843        enforceNotIsolatedCaller("keyguardGoingAway");
6844        final long token = Binder.clearCallingIdentity();
6845        try {
6846            synchronized (this) {
6847                mKeyguardController.keyguardGoingAway(flags);
6848            }
6849        } finally {
6850            Binder.restoreCallingIdentity(token);
6851        }
6852    }
6853
6854    /**
6855     * @return whther the keyguard is currently locked.
6856     */
6857    boolean isKeyguardLocked() {
6858        return mKeyguardController.isKeyguardLocked();
6859    }
6860
6861    final void finishBooting() {
6862        synchronized (this) {
6863            if (!mBootAnimationComplete) {
6864                mCallFinishBooting = true;
6865                return;
6866            }
6867            mCallFinishBooting = false;
6868        }
6869
6870        ArraySet<String> completedIsas = new ArraySet<String>();
6871        for (String abi : Build.SUPPORTED_ABIS) {
6872            Process.zygoteProcess.establishZygoteConnectionForAbi(abi);
6873            final String instructionSet = VMRuntime.getInstructionSet(abi);
6874            if (!completedIsas.contains(instructionSet)) {
6875                try {
6876                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6877                } catch (InstallerException e) {
6878                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6879                            e.getMessage() +")");
6880                }
6881                completedIsas.add(instructionSet);
6882            }
6883        }
6884
6885        IntentFilter pkgFilter = new IntentFilter();
6886        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6887        pkgFilter.addDataScheme("package");
6888        mContext.registerReceiver(new BroadcastReceiver() {
6889            @Override
6890            public void onReceive(Context context, Intent intent) {
6891                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6892                if (pkgs != null) {
6893                    for (String pkg : pkgs) {
6894                        synchronized (ActivityManagerService.this) {
6895                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6896                                    0, "query restart")) {
6897                                setResultCode(Activity.RESULT_OK);
6898                                return;
6899                            }
6900                        }
6901                    }
6902                }
6903            }
6904        }, pkgFilter);
6905
6906        IntentFilter dumpheapFilter = new IntentFilter();
6907        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6908        mContext.registerReceiver(new BroadcastReceiver() {
6909            @Override
6910            public void onReceive(Context context, Intent intent) {
6911                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6912                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6913                } else {
6914                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6915                }
6916            }
6917        }, dumpheapFilter);
6918
6919        // Let system services know.
6920        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6921
6922        synchronized (this) {
6923            // Ensure that any processes we had put on hold are now started
6924            // up.
6925            final int NP = mProcessesOnHold.size();
6926            if (NP > 0) {
6927                ArrayList<ProcessRecord> procs =
6928                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6929                for (int ip=0; ip<NP; ip++) {
6930                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6931                            + procs.get(ip));
6932                    startProcessLocked(procs.get(ip), "on-hold", null);
6933                }
6934            }
6935
6936            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6937                // Start looking for apps that are abusing wake locks.
6938                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6939                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6940                // Tell anyone interested that we are done booting!
6941                SystemProperties.set("sys.boot_completed", "1");
6942
6943                // And trigger dev.bootcomplete if we are not showing encryption progress
6944                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6945                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6946                    SystemProperties.set("dev.bootcomplete", "1");
6947                }
6948                mUserController.sendBootCompletedLocked(
6949                        new IIntentReceiver.Stub() {
6950                            @Override
6951                            public void performReceive(Intent intent, int resultCode,
6952                                    String data, Bundle extras, boolean ordered,
6953                                    boolean sticky, int sendingUser) {
6954                                synchronized (ActivityManagerService.this) {
6955                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6956                                            true, false);
6957                                }
6958                            }
6959                        });
6960                scheduleStartProfilesLocked();
6961            }
6962        }
6963    }
6964
6965    @Override
6966    public void bootAnimationComplete() {
6967        final boolean callFinishBooting;
6968        synchronized (this) {
6969            callFinishBooting = mCallFinishBooting;
6970            mBootAnimationComplete = true;
6971        }
6972        if (callFinishBooting) {
6973            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6974            finishBooting();
6975            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6976        }
6977    }
6978
6979    final void ensureBootCompleted() {
6980        boolean booting;
6981        boolean enableScreen;
6982        synchronized (this) {
6983            booting = mBooting;
6984            mBooting = false;
6985            enableScreen = !mBooted;
6986            mBooted = true;
6987        }
6988
6989        if (booting) {
6990            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6991            finishBooting();
6992            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6993        }
6994
6995        if (enableScreen) {
6996            enableScreenAfterBoot();
6997        }
6998    }
6999
7000    @Override
7001    public final void activityResumed(IBinder token) {
7002        final long origId = Binder.clearCallingIdentity();
7003        synchronized(this) {
7004            ActivityRecord.activityResumedLocked(token);
7005            mWindowManager.notifyAppResumedFinished(token);
7006        }
7007        Binder.restoreCallingIdentity(origId);
7008    }
7009
7010    @Override
7011    public final void activityPaused(IBinder token) {
7012        final long origId = Binder.clearCallingIdentity();
7013        synchronized(this) {
7014            ActivityStack stack = ActivityRecord.getStackLocked(token);
7015            if (stack != null) {
7016                stack.activityPausedLocked(token, false);
7017            }
7018        }
7019        Binder.restoreCallingIdentity(origId);
7020    }
7021
7022    @Override
7023    public final void activityStopped(IBinder token, Bundle icicle,
7024            PersistableBundle persistentState, CharSequence description) {
7025        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
7026
7027        // Refuse possible leaked file descriptors
7028        if (icicle != null && icicle.hasFileDescriptors()) {
7029            throw new IllegalArgumentException("File descriptors passed in Bundle");
7030        }
7031
7032        final long origId = Binder.clearCallingIdentity();
7033
7034        synchronized (this) {
7035            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7036            if (r != null) {
7037                r.activityStoppedLocked(icicle, persistentState, description);
7038            }
7039        }
7040
7041        trimApplications();
7042
7043        Binder.restoreCallingIdentity(origId);
7044    }
7045
7046    @Override
7047    public final void activityDestroyed(IBinder token) {
7048        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
7049        synchronized (this) {
7050            ActivityStack stack = ActivityRecord.getStackLocked(token);
7051            if (stack != null) {
7052                stack.activityDestroyedLocked(token, "activityDestroyed");
7053            }
7054        }
7055    }
7056
7057    @Override
7058    public final void activityRelaunched(IBinder token) {
7059        final long origId = Binder.clearCallingIdentity();
7060        synchronized (this) {
7061            mStackSupervisor.activityRelaunchedLocked(token);
7062        }
7063        Binder.restoreCallingIdentity(origId);
7064    }
7065
7066    @Override
7067    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
7068            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
7069        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
7070                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
7071        synchronized (this) {
7072            ActivityRecord record = ActivityRecord.isInStackLocked(token);
7073            if (record == null) {
7074                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
7075                        + "found for: " + token);
7076            }
7077            record.setSizeConfigurations(horizontalSizeConfiguration,
7078                    verticalSizeConfigurations, smallestSizeConfigurations);
7079        }
7080    }
7081
7082    @Override
7083    public final void backgroundResourcesReleased(IBinder token) {
7084        final long origId = Binder.clearCallingIdentity();
7085        try {
7086            synchronized (this) {
7087                ActivityStack stack = ActivityRecord.getStackLocked(token);
7088                if (stack != null) {
7089                    stack.backgroundResourcesReleased();
7090                }
7091            }
7092        } finally {
7093            Binder.restoreCallingIdentity(origId);
7094        }
7095    }
7096
7097    @Override
7098    public final void notifyLaunchTaskBehindComplete(IBinder token) {
7099        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7100    }
7101
7102    @Override
7103    public final void notifyEnterAnimationComplete(IBinder token) {
7104        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7105    }
7106
7107    @Override
7108    public String getCallingPackage(IBinder token) {
7109        synchronized (this) {
7110            ActivityRecord r = getCallingRecordLocked(token);
7111            return r != null ? r.info.packageName : null;
7112        }
7113    }
7114
7115    @Override
7116    public ComponentName getCallingActivity(IBinder token) {
7117        synchronized (this) {
7118            ActivityRecord r = getCallingRecordLocked(token);
7119            return r != null ? r.intent.getComponent() : null;
7120        }
7121    }
7122
7123    private ActivityRecord getCallingRecordLocked(IBinder token) {
7124        ActivityRecord r = ActivityRecord.isInStackLocked(token);
7125        if (r == null) {
7126            return null;
7127        }
7128        return r.resultTo;
7129    }
7130
7131    @Override
7132    public ComponentName getActivityClassForToken(IBinder token) {
7133        synchronized(this) {
7134            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7135            if (r == null) {
7136                return null;
7137            }
7138            return r.intent.getComponent();
7139        }
7140    }
7141
7142    @Override
7143    public String getPackageForToken(IBinder token) {
7144        synchronized(this) {
7145            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7146            if (r == null) {
7147                return null;
7148            }
7149            return r.packageName;
7150        }
7151    }
7152
7153    @Override
7154    public boolean isRootVoiceInteraction(IBinder token) {
7155        synchronized(this) {
7156            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7157            if (r == null) {
7158                return false;
7159            }
7160            return r.rootVoiceInteraction;
7161        }
7162    }
7163
7164    @Override
7165    public IIntentSender getIntentSender(int type,
7166            String packageName, IBinder token, String resultWho,
7167            int requestCode, Intent[] intents, String[] resolvedTypes,
7168            int flags, Bundle bOptions, int userId) {
7169        enforceNotIsolatedCaller("getIntentSender");
7170        // Refuse possible leaked file descriptors
7171        if (intents != null) {
7172            if (intents.length < 1) {
7173                throw new IllegalArgumentException("Intents array length must be >= 1");
7174            }
7175            for (int i=0; i<intents.length; i++) {
7176                Intent intent = intents[i];
7177                if (intent != null) {
7178                    if (intent.hasFileDescriptors()) {
7179                        throw new IllegalArgumentException("File descriptors passed in Intent");
7180                    }
7181                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7182                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7183                        throw new IllegalArgumentException(
7184                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7185                    }
7186                    intents[i] = new Intent(intent);
7187                }
7188            }
7189            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7190                throw new IllegalArgumentException(
7191                        "Intent array length does not match resolvedTypes length");
7192            }
7193        }
7194        if (bOptions != null) {
7195            if (bOptions.hasFileDescriptors()) {
7196                throw new IllegalArgumentException("File descriptors passed in options");
7197            }
7198        }
7199
7200        synchronized(this) {
7201            int callingUid = Binder.getCallingUid();
7202            int origUserId = userId;
7203            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7204                    type == ActivityManager.INTENT_SENDER_BROADCAST,
7205                    ALLOW_NON_FULL, "getIntentSender", null);
7206            if (origUserId == UserHandle.USER_CURRENT) {
7207                // We don't want to evaluate this until the pending intent is
7208                // actually executed.  However, we do want to always do the
7209                // security checking for it above.
7210                userId = UserHandle.USER_CURRENT;
7211            }
7212            try {
7213                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7214                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7215                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7216                    if (!UserHandle.isSameApp(callingUid, uid)) {
7217                        String msg = "Permission Denial: getIntentSender() from pid="
7218                            + Binder.getCallingPid()
7219                            + ", uid=" + Binder.getCallingUid()
7220                            + ", (need uid=" + uid + ")"
7221                            + " is not allowed to send as package " + packageName;
7222                        Slog.w(TAG, msg);
7223                        throw new SecurityException(msg);
7224                    }
7225                }
7226
7227                return getIntentSenderLocked(type, packageName, callingUid, userId,
7228                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7229
7230            } catch (RemoteException e) {
7231                throw new SecurityException(e);
7232            }
7233        }
7234    }
7235
7236    IIntentSender getIntentSenderLocked(int type, String packageName,
7237            int callingUid, int userId, IBinder token, String resultWho,
7238            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7239            Bundle bOptions) {
7240        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7241        ActivityRecord activity = null;
7242        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7243            activity = ActivityRecord.isInStackLocked(token);
7244            if (activity == null) {
7245                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7246                return null;
7247            }
7248            if (activity.finishing) {
7249                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7250                return null;
7251            }
7252        }
7253
7254        // We're going to be splicing together extras before sending, so we're
7255        // okay poking into any contained extras.
7256        if (intents != null) {
7257            for (int i = 0; i < intents.length; i++) {
7258                intents[i].setDefusable(true);
7259            }
7260        }
7261        Bundle.setDefusable(bOptions, true);
7262
7263        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7264        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7265        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7266        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7267                |PendingIntent.FLAG_UPDATE_CURRENT);
7268
7269        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7270                type, packageName, activity, resultWho,
7271                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7272        WeakReference<PendingIntentRecord> ref;
7273        ref = mIntentSenderRecords.get(key);
7274        PendingIntentRecord rec = ref != null ? ref.get() : null;
7275        if (rec != null) {
7276            if (!cancelCurrent) {
7277                if (updateCurrent) {
7278                    if (rec.key.requestIntent != null) {
7279                        rec.key.requestIntent.replaceExtras(intents != null ?
7280                                intents[intents.length - 1] : null);
7281                    }
7282                    if (intents != null) {
7283                        intents[intents.length-1] = rec.key.requestIntent;
7284                        rec.key.allIntents = intents;
7285                        rec.key.allResolvedTypes = resolvedTypes;
7286                    } else {
7287                        rec.key.allIntents = null;
7288                        rec.key.allResolvedTypes = null;
7289                    }
7290                }
7291                return rec;
7292            }
7293            rec.canceled = true;
7294            mIntentSenderRecords.remove(key);
7295        }
7296        if (noCreate) {
7297            return rec;
7298        }
7299        rec = new PendingIntentRecord(this, key, callingUid);
7300        mIntentSenderRecords.put(key, rec.ref);
7301        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7302            if (activity.pendingResults == null) {
7303                activity.pendingResults
7304                        = new HashSet<WeakReference<PendingIntentRecord>>();
7305            }
7306            activity.pendingResults.add(rec.ref);
7307        }
7308        return rec;
7309    }
7310
7311    @Override
7312    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7313            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7314        if (target instanceof PendingIntentRecord) {
7315            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7316                    finishedReceiver, requiredPermission, options);
7317        } else {
7318            if (intent == null) {
7319                // Weird case: someone has given us their own custom IIntentSender, and now
7320                // they have someone else trying to send to it but of course this isn't
7321                // really a PendingIntent, so there is no base Intent, and the caller isn't
7322                // supplying an Intent... but we never want to dispatch a null Intent to
7323                // a receiver, so um...  let's make something up.
7324                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7325                intent = new Intent(Intent.ACTION_MAIN);
7326            }
7327            try {
7328                target.send(code, intent, resolvedType, null, requiredPermission, options);
7329            } catch (RemoteException e) {
7330            }
7331            // Platform code can rely on getting a result back when the send is done, but if
7332            // this intent sender is from outside of the system we can't rely on it doing that.
7333            // So instead we don't give it the result receiver, and instead just directly
7334            // report the finish immediately.
7335            if (finishedReceiver != null) {
7336                try {
7337                    finishedReceiver.performReceive(intent, 0,
7338                            null, null, false, false, UserHandle.getCallingUserId());
7339                } catch (RemoteException e) {
7340                }
7341            }
7342            return 0;
7343        }
7344    }
7345
7346    /**
7347     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7348     */
7349    void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7350        if (DEBUG_WHITELISTS) {
7351            Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7352                    + targetUid + ", " + duration + ")");
7353        }
7354
7355        if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid)
7356                != PackageManager.PERMISSION_GRANTED) {
7357            synchronized (mPidsSelfLocked) {
7358                final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7359                if (pr == null) {
7360                    Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid "
7361                            + callerPid);
7362                    return;
7363                }
7364                if (!pr.whitelistManager) {
7365                    if (DEBUG_WHITELISTS) {
7366                        Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid
7367                                + ": pid " + callerPid + " is not allowed");
7368                    }
7369                    return;
7370                }
7371            }
7372        }
7373
7374        final long token = Binder.clearCallingIdentity();
7375        try {
7376            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7377                    true, "pe from uid:" + callerUid);
7378        } finally {
7379            Binder.restoreCallingIdentity(token);
7380        }
7381    }
7382
7383    @Override
7384    public void cancelIntentSender(IIntentSender sender) {
7385        if (!(sender instanceof PendingIntentRecord)) {
7386            return;
7387        }
7388        synchronized(this) {
7389            PendingIntentRecord rec = (PendingIntentRecord)sender;
7390            try {
7391                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7392                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7393                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7394                    String msg = "Permission Denial: cancelIntentSender() from pid="
7395                        + Binder.getCallingPid()
7396                        + ", uid=" + Binder.getCallingUid()
7397                        + " is not allowed to cancel packges "
7398                        + rec.key.packageName;
7399                    Slog.w(TAG, msg);
7400                    throw new SecurityException(msg);
7401                }
7402            } catch (RemoteException e) {
7403                throw new SecurityException(e);
7404            }
7405            cancelIntentSenderLocked(rec, true);
7406        }
7407    }
7408
7409    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7410        rec.canceled = true;
7411        mIntentSenderRecords.remove(rec.key);
7412        if (cleanActivity && rec.key.activity != null) {
7413            rec.key.activity.pendingResults.remove(rec.ref);
7414        }
7415    }
7416
7417    @Override
7418    public String getPackageForIntentSender(IIntentSender pendingResult) {
7419        if (!(pendingResult instanceof PendingIntentRecord)) {
7420            return null;
7421        }
7422        try {
7423            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7424            return res.key.packageName;
7425        } catch (ClassCastException e) {
7426        }
7427        return null;
7428    }
7429
7430    @Override
7431    public int getUidForIntentSender(IIntentSender sender) {
7432        if (sender instanceof PendingIntentRecord) {
7433            try {
7434                PendingIntentRecord res = (PendingIntentRecord)sender;
7435                return res.uid;
7436            } catch (ClassCastException e) {
7437            }
7438        }
7439        return -1;
7440    }
7441
7442    @Override
7443    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7444        if (!(pendingResult instanceof PendingIntentRecord)) {
7445            return false;
7446        }
7447        try {
7448            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7449            if (res.key.allIntents == null) {
7450                return false;
7451            }
7452            for (int i=0; i<res.key.allIntents.length; i++) {
7453                Intent intent = res.key.allIntents[i];
7454                if (intent.getPackage() != null && intent.getComponent() != null) {
7455                    return false;
7456                }
7457            }
7458            return true;
7459        } catch (ClassCastException e) {
7460        }
7461        return false;
7462    }
7463
7464    @Override
7465    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7466        if (!(pendingResult instanceof PendingIntentRecord)) {
7467            return false;
7468        }
7469        try {
7470            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7471            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7472                return true;
7473            }
7474            return false;
7475        } catch (ClassCastException e) {
7476        }
7477        return false;
7478    }
7479
7480    @Override
7481    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7482        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7483                "getIntentForIntentSender()");
7484        if (!(pendingResult instanceof PendingIntentRecord)) {
7485            return null;
7486        }
7487        try {
7488            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7489            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7490        } catch (ClassCastException e) {
7491        }
7492        return null;
7493    }
7494
7495    @Override
7496    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7497        if (!(pendingResult instanceof PendingIntentRecord)) {
7498            return null;
7499        }
7500        try {
7501            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7502            synchronized (this) {
7503                return getTagForIntentSenderLocked(res, prefix);
7504            }
7505        } catch (ClassCastException e) {
7506        }
7507        return null;
7508    }
7509
7510    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7511        final Intent intent = res.key.requestIntent;
7512        if (intent != null) {
7513            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7514                    || res.lastTagPrefix.equals(prefix))) {
7515                return res.lastTag;
7516            }
7517            res.lastTagPrefix = prefix;
7518            final StringBuilder sb = new StringBuilder(128);
7519            if (prefix != null) {
7520                sb.append(prefix);
7521            }
7522            if (intent.getAction() != null) {
7523                sb.append(intent.getAction());
7524            } else if (intent.getComponent() != null) {
7525                intent.getComponent().appendShortString(sb);
7526            } else {
7527                sb.append("?");
7528            }
7529            return res.lastTag = sb.toString();
7530        }
7531        return null;
7532    }
7533
7534    @Override
7535    public void setProcessLimit(int max) {
7536        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7537                "setProcessLimit()");
7538        synchronized (this) {
7539            mConstants.setOverrideMaxCachedProcesses(max);
7540        }
7541        trimApplications();
7542    }
7543
7544    @Override
7545    public int getProcessLimit() {
7546        synchronized (this) {
7547            return mConstants.getOverrideMaxCachedProcesses();
7548        }
7549    }
7550
7551    void foregroundTokenDied(ForegroundToken token) {
7552        synchronized (ActivityManagerService.this) {
7553            synchronized (mPidsSelfLocked) {
7554                ForegroundToken cur
7555                    = mForegroundProcesses.get(token.pid);
7556                if (cur != token) {
7557                    return;
7558                }
7559                mForegroundProcesses.remove(token.pid);
7560                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7561                if (pr == null) {
7562                    return;
7563                }
7564                pr.forcingToForeground = null;
7565                updateProcessForegroundLocked(pr, false, false);
7566            }
7567            updateOomAdjLocked();
7568        }
7569    }
7570
7571    @Override
7572    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7573        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7574                "setProcessForeground()");
7575        synchronized(this) {
7576            boolean changed = false;
7577
7578            synchronized (mPidsSelfLocked) {
7579                ProcessRecord pr = mPidsSelfLocked.get(pid);
7580                if (pr == null && isForeground) {
7581                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7582                    return;
7583                }
7584                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7585                if (oldToken != null) {
7586                    oldToken.token.unlinkToDeath(oldToken, 0);
7587                    mForegroundProcesses.remove(pid);
7588                    if (pr != null) {
7589                        pr.forcingToForeground = null;
7590                    }
7591                    changed = true;
7592                }
7593                if (isForeground && token != null) {
7594                    ForegroundToken newToken = new ForegroundToken() {
7595                        @Override
7596                        public void binderDied() {
7597                            foregroundTokenDied(this);
7598                        }
7599                    };
7600                    newToken.pid = pid;
7601                    newToken.token = token;
7602                    try {
7603                        token.linkToDeath(newToken, 0);
7604                        mForegroundProcesses.put(pid, newToken);
7605                        pr.forcingToForeground = token;
7606                        changed = true;
7607                    } catch (RemoteException e) {
7608                        // If the process died while doing this, we will later
7609                        // do the cleanup with the process death link.
7610                    }
7611                }
7612            }
7613
7614            if (changed) {
7615                updateOomAdjLocked();
7616            }
7617        }
7618    }
7619
7620    @Override
7621    public boolean isAppForeground(int uid) throws RemoteException {
7622        synchronized (this) {
7623            UidRecord uidRec = mActiveUids.get(uid);
7624            if (uidRec == null || uidRec.idle) {
7625                return false;
7626            }
7627            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7628        }
7629    }
7630
7631    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7632    // be guarded by permission checking.
7633    int getUidState(int uid) {
7634        synchronized (this) {
7635            UidRecord uidRec = mActiveUids.get(uid);
7636            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7637        }
7638    }
7639
7640    @Override
7641    public boolean isInMultiWindowMode(IBinder token) {
7642        final long origId = Binder.clearCallingIdentity();
7643        try {
7644            synchronized(this) {
7645                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7646                if (r == null) {
7647                    return false;
7648                }
7649                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7650                return !r.task.mFullscreen;
7651            }
7652        } finally {
7653            Binder.restoreCallingIdentity(origId);
7654        }
7655    }
7656
7657    @Override
7658    public boolean isInPictureInPictureMode(IBinder token) {
7659        final long origId = Binder.clearCallingIdentity();
7660        try {
7661            synchronized(this) {
7662                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7663                if (stack == null) {
7664                    return false;
7665                }
7666                return stack.mStackId == PINNED_STACK_ID;
7667            }
7668        } finally {
7669            Binder.restoreCallingIdentity(origId);
7670        }
7671    }
7672
7673    @Override
7674    public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureArgs args) {
7675        final long origId = Binder.clearCallingIdentity();
7676        try {
7677            synchronized(this) {
7678                final ActivityRecord r = ensureValidPictureInPictureActivityArgsLocked(
7679                        "enterPictureInPictureMode", token, args);
7680
7681                // Activity supports picture-in-picture, now check that we can enter PiP at this
7682                // point, if it is
7683                if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
7684                        false /* noThrow */)) {
7685                    return false;
7686                }
7687
7688                final Runnable enterPipRunnable = () -> {
7689                    // Only update the saved args from the args that are set
7690                    r.pictureInPictureArgs.copyOnlySet(args);
7691                    final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
7692                    final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
7693                    final Rect bounds = mWindowManager.getPictureInPictureBounds(DEFAULT_DISPLAY,
7694                            aspectRatio);
7695                    mStackSupervisor.moveActivityToPinnedStackLocked(r, "enterPictureInPictureMode",
7696                            bounds, true /* moveHomeStackToFront */);
7697                    final ActivityStack stack = mStackSupervisor.getStack(PINNED_STACK_ID);
7698                    stack.setPictureInPictureAspectRatio(aspectRatio);
7699                    stack.setPictureInPictureActions(actions);
7700
7701                    MetricsLogger.action(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_ENTERED,
7702                            r.supportsPictureInPictureWhilePausing);
7703                    logPictureInPictureArgs(args);
7704                };
7705
7706                if (isKeyguardLocked()) {
7707                    // If the keyguard is showing or occluded, then try and dismiss it before
7708                    // entering picture-in-picture (this will prompt the user to authenticate if the
7709                    // device is currently locked).
7710                    try {
7711                        dismissKeyguard(token, new IKeyguardDismissCallback.Stub() {
7712                            @Override
7713                            public void onDismissError() throws RemoteException {
7714                                // Do nothing
7715                            }
7716
7717                            @Override
7718                            public void onDismissSucceeded() throws RemoteException {
7719                                mHandler.post(enterPipRunnable);
7720                            }
7721
7722                            @Override
7723                            public void onDismissCancelled() throws RemoteException {
7724                                // Do nothing
7725                            }
7726                        });
7727                    } catch (RemoteException e) {
7728                        // Local call
7729                    }
7730                } else {
7731                    // Enter picture in picture immediately otherwise
7732                    enterPipRunnable.run();
7733                }
7734                return true;
7735            }
7736        } finally {
7737            Binder.restoreCallingIdentity(origId);
7738        }
7739    }
7740
7741    @Override
7742    public void setPictureInPictureArgs(IBinder token, final PictureInPictureArgs args) {
7743        final long origId = Binder.clearCallingIdentity();
7744        try {
7745            synchronized(this) {
7746                final ActivityRecord r = ensureValidPictureInPictureActivityArgsLocked(
7747                        "setPictureInPictureArgs", token, args);
7748
7749                // Only update the saved args from the args that are set
7750                r.pictureInPictureArgs.copyOnlySet(args);
7751                final ActivityStack stack = r.getStack();
7752                if (stack.getStackId() == PINNED_STACK_ID) {
7753                    // If the activity is already in picture-in-picture, update the pinned stack now
7754                    stack.setPictureInPictureAspectRatio(r.pictureInPictureArgs.getAspectRatio());
7755                    stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
7756                }
7757                logPictureInPictureArgs(args);
7758            }
7759        } finally {
7760            Binder.restoreCallingIdentity(origId);
7761        }
7762    }
7763
7764    private void logPictureInPictureArgs(PictureInPictureArgs args) {
7765        if (args.hasSetActions()) {
7766            MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
7767                    args.getActions().size());
7768        }
7769        if (args.hasSetAspectRatio()) {
7770            LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
7771            lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, args.getAspectRatio());
7772            MetricsLogger.action(lm);
7773        }
7774    }
7775
7776    /**
7777     * Checks the state of the system and the activity associated with the given {@param token} to
7778     * verify that picture-in-picture is supported for that activity.
7779     *
7780     * @return the activity record for the given {@param token} if all the checks pass.
7781     */
7782    private ActivityRecord ensureValidPictureInPictureActivityArgsLocked(String caller,
7783            IBinder token, PictureInPictureArgs args) {
7784        if (!mSupportsPictureInPicture) {
7785            throw new IllegalStateException(caller
7786                    + ": Device doesn't support picture-in-picture mode.");
7787        }
7788
7789        final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7790        if (r == null) {
7791            throw new IllegalStateException(caller
7792                    + ": Can't find activity for token=" + token);
7793        }
7794
7795        if (!r.supportsPictureInPicture()) {
7796            throw new IllegalStateException(caller
7797                    + ": Current activity does not support picture-in-picture.");
7798        }
7799
7800        if (!StackId.isAllowedToEnterPictureInPicture(r.getStack().getStackId())) {
7801            throw new IllegalStateException(caller
7802                    + ": Activities on the home, assistant, or recents stack not supported");
7803        }
7804
7805        if (args.hasSetAspectRatio()
7806                && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
7807                        args.getAspectRatio())) {
7808            final float minAspectRatio = mContext.getResources().getFloat(
7809                    com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
7810            final float maxAspectRatio = mContext.getResources().getFloat(
7811                    com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
7812            throw new IllegalArgumentException(String.format(caller
7813                    + ": Aspect ratio is too extreme (must be between %f and %f).",
7814                            minAspectRatio, maxAspectRatio));
7815        }
7816
7817        if (args.hasSetActions()
7818                && args.getActions().size() > ActivityManager.getMaxNumPictureInPictureActions()) {
7819            throw new IllegalArgumentException(String.format(caller + ": Invalid number of"
7820                    + "picture-in-picture actions.  Only a maximum of %d actions allowed",
7821                            ActivityManager.getMaxNumPictureInPictureActions()));
7822        }
7823
7824        return r;
7825    }
7826
7827    // =========================================================
7828    // PROCESS INFO
7829    // =========================================================
7830
7831    static class ProcessInfoService extends IProcessInfoService.Stub {
7832        final ActivityManagerService mActivityManagerService;
7833        ProcessInfoService(ActivityManagerService activityManagerService) {
7834            mActivityManagerService = activityManagerService;
7835        }
7836
7837        @Override
7838        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7839            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7840                    /*in*/ pids, /*out*/ states, null);
7841        }
7842
7843        @Override
7844        public void getProcessStatesAndOomScoresFromPids(
7845                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7846            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7847                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7848        }
7849    }
7850
7851    /**
7852     * For each PID in the given input array, write the current process state
7853     * for that process into the states array, or -1 to indicate that no
7854     * process with the given PID exists. If scores array is provided, write
7855     * the oom score for the process into the scores array, with INVALID_ADJ
7856     * indicating the PID doesn't exist.
7857     */
7858    public void getProcessStatesAndOomScoresForPIDs(
7859            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7860        if (scores != null) {
7861            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7862                    "getProcessStatesAndOomScoresForPIDs()");
7863        }
7864
7865        if (pids == null) {
7866            throw new NullPointerException("pids");
7867        } else if (states == null) {
7868            throw new NullPointerException("states");
7869        } else if (pids.length != states.length) {
7870            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7871        } else if (scores != null && pids.length != scores.length) {
7872            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7873        }
7874
7875        synchronized (mPidsSelfLocked) {
7876            for (int i = 0; i < pids.length; i++) {
7877                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7878                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7879                        pr.curProcState;
7880                if (scores != null) {
7881                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7882                }
7883            }
7884        }
7885    }
7886
7887    // =========================================================
7888    // PERMISSIONS
7889    // =========================================================
7890
7891    static class PermissionController extends IPermissionController.Stub {
7892        ActivityManagerService mActivityManagerService;
7893        PermissionController(ActivityManagerService activityManagerService) {
7894            mActivityManagerService = activityManagerService;
7895        }
7896
7897        @Override
7898        public boolean checkPermission(String permission, int pid, int uid) {
7899            return mActivityManagerService.checkPermission(permission, pid,
7900                    uid) == PackageManager.PERMISSION_GRANTED;
7901        }
7902
7903        @Override
7904        public String[] getPackagesForUid(int uid) {
7905            return mActivityManagerService.mContext.getPackageManager()
7906                    .getPackagesForUid(uid);
7907        }
7908
7909        @Override
7910        public boolean isRuntimePermission(String permission) {
7911            try {
7912                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7913                        .getPermissionInfo(permission, 0);
7914                return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
7915                        == PermissionInfo.PROTECTION_DANGEROUS;
7916            } catch (NameNotFoundException nnfe) {
7917                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7918            }
7919            return false;
7920        }
7921    }
7922
7923    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7924        @Override
7925        public int checkComponentPermission(String permission, int pid, int uid,
7926                int owningUid, boolean exported) {
7927            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7928                    owningUid, exported);
7929        }
7930
7931        @Override
7932        public Object getAMSLock() {
7933            return ActivityManagerService.this;
7934        }
7935    }
7936
7937    /**
7938     * This can be called with or without the global lock held.
7939     */
7940    int checkComponentPermission(String permission, int pid, int uid,
7941            int owningUid, boolean exported) {
7942        if (pid == MY_PID) {
7943            return PackageManager.PERMISSION_GRANTED;
7944        }
7945        return ActivityManager.checkComponentPermission(permission, uid,
7946                owningUid, exported);
7947    }
7948
7949    /**
7950     * As the only public entry point for permissions checking, this method
7951     * can enforce the semantic that requesting a check on a null global
7952     * permission is automatically denied.  (Internally a null permission
7953     * string is used when calling {@link #checkComponentPermission} in cases
7954     * when only uid-based security is needed.)
7955     *
7956     * This can be called with or without the global lock held.
7957     */
7958    @Override
7959    public int checkPermission(String permission, int pid, int uid) {
7960        if (permission == null) {
7961            return PackageManager.PERMISSION_DENIED;
7962        }
7963        return checkComponentPermission(permission, pid, uid, -1, true);
7964    }
7965
7966    @Override
7967    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7968        if (permission == null) {
7969            return PackageManager.PERMISSION_DENIED;
7970        }
7971
7972        // We might be performing an operation on behalf of an indirect binder
7973        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7974        // client identity accordingly before proceeding.
7975        Identity tlsIdentity = sCallerIdentity.get();
7976        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7977            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7978                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7979            uid = tlsIdentity.uid;
7980            pid = tlsIdentity.pid;
7981        }
7982
7983        return checkComponentPermission(permission, pid, uid, -1, true);
7984    }
7985
7986    /**
7987     * Binder IPC calls go through the public entry point.
7988     * This can be called with or without the global lock held.
7989     */
7990    int checkCallingPermission(String permission) {
7991        return checkPermission(permission,
7992                Binder.getCallingPid(),
7993                UserHandle.getAppId(Binder.getCallingUid()));
7994    }
7995
7996    /**
7997     * This can be called with or without the global lock held.
7998     */
7999    void enforceCallingPermission(String permission, String func) {
8000        if (checkCallingPermission(permission)
8001                == PackageManager.PERMISSION_GRANTED) {
8002            return;
8003        }
8004
8005        String msg = "Permission Denial: " + func + " from pid="
8006                + Binder.getCallingPid()
8007                + ", uid=" + Binder.getCallingUid()
8008                + " requires " + permission;
8009        Slog.w(TAG, msg);
8010        throw new SecurityException(msg);
8011    }
8012
8013    /**
8014     * Determine if UID is holding permissions required to access {@link Uri} in
8015     * the given {@link ProviderInfo}. Final permission checking is always done
8016     * in {@link ContentProvider}.
8017     */
8018    private final boolean checkHoldingPermissionsLocked(
8019            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
8020        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8021                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
8022        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
8023            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
8024                    != PERMISSION_GRANTED) {
8025                return false;
8026            }
8027        }
8028        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
8029    }
8030
8031    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
8032            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
8033        if (pi.applicationInfo.uid == uid) {
8034            return true;
8035        } else if (!pi.exported) {
8036            return false;
8037        }
8038
8039        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
8040        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
8041        try {
8042            // check if target holds top-level <provider> permissions
8043            if (!readMet && pi.readPermission != null && considerUidPermissions
8044                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
8045                readMet = true;
8046            }
8047            if (!writeMet && pi.writePermission != null && considerUidPermissions
8048                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
8049                writeMet = true;
8050            }
8051
8052            // track if unprotected read/write is allowed; any denied
8053            // <path-permission> below removes this ability
8054            boolean allowDefaultRead = pi.readPermission == null;
8055            boolean allowDefaultWrite = pi.writePermission == null;
8056
8057            // check if target holds any <path-permission> that match uri
8058            final PathPermission[] pps = pi.pathPermissions;
8059            if (pps != null) {
8060                final String path = grantUri.uri.getPath();
8061                int i = pps.length;
8062                while (i > 0 && (!readMet || !writeMet)) {
8063                    i--;
8064                    PathPermission pp = pps[i];
8065                    if (pp.match(path)) {
8066                        if (!readMet) {
8067                            final String pprperm = pp.getReadPermission();
8068                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8069                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
8070                                    + ": match=" + pp.match(path)
8071                                    + " check=" + pm.checkUidPermission(pprperm, uid));
8072                            if (pprperm != null) {
8073                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
8074                                        == PERMISSION_GRANTED) {
8075                                    readMet = true;
8076                                } else {
8077                                    allowDefaultRead = false;
8078                                }
8079                            }
8080                        }
8081                        if (!writeMet) {
8082                            final String ppwperm = pp.getWritePermission();
8083                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8084                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
8085                                    + ": match=" + pp.match(path)
8086                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
8087                            if (ppwperm != null) {
8088                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
8089                                        == PERMISSION_GRANTED) {
8090                                    writeMet = true;
8091                                } else {
8092                                    allowDefaultWrite = false;
8093                                }
8094                            }
8095                        }
8096                    }
8097                }
8098            }
8099
8100            // grant unprotected <provider> read/write, if not blocked by
8101            // <path-permission> above
8102            if (allowDefaultRead) readMet = true;
8103            if (allowDefaultWrite) writeMet = true;
8104
8105        } catch (RemoteException e) {
8106            return false;
8107        }
8108
8109        return readMet && writeMet;
8110    }
8111
8112    public boolean isAppStartModeDisabled(int uid, String packageName) {
8113        synchronized (this) {
8114            return getAppStartModeLocked(uid, packageName, 0, -1, false, true)
8115                    == ActivityManager.APP_START_MODE_DISABLED;
8116        }
8117    }
8118
8119    // Unified app-op and target sdk check
8120    int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8121        // Apps that target O+ are always subject to background check
8122        if (mConstants.ENFORCE_BG_CHECK && packageTargetSdk >= Build.VERSION_CODES.O) {
8123            if (DEBUG_BACKGROUND_CHECK) {
8124                Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted");
8125            }
8126            return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8127        }
8128        // ...and legacy apps get an AppOp check
8129        int appop = mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND,
8130                uid, packageName);
8131        if (DEBUG_BACKGROUND_CHECK) {
8132            Slog.i(TAG, "Legacy app " + uid + "/" + packageName + " bg appop " + appop);
8133        }
8134        switch (appop) {
8135            case AppOpsManager.MODE_ALLOWED:
8136                return ActivityManager.APP_START_MODE_NORMAL;
8137            case AppOpsManager.MODE_IGNORED:
8138                return ActivityManager.APP_START_MODE_DELAYED;
8139            default:
8140                return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8141        }
8142    }
8143
8144    // Service launch is available to apps with run-in-background exemptions but
8145    // some other background operations are not.  If we're doing a check
8146    // of service-launch policy, allow those callers to proceed unrestricted.
8147    int appServicesRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8148        // Persistent app?
8149        if (mPackageManagerInt.isPackagePersistent(packageName)) {
8150            if (DEBUG_BACKGROUND_CHECK) {
8151                Slog.i(TAG, "App " + uid + "/" + packageName
8152                        + " is persistent; not restricted in background");
8153            }
8154            return ActivityManager.APP_START_MODE_NORMAL;
8155        }
8156
8157        // Non-persistent but background whitelisted?
8158        if (uidOnBackgroundWhitelist(uid)) {
8159            if (DEBUG_BACKGROUND_CHECK) {
8160                Slog.i(TAG, "App " + uid + "/" + packageName
8161                        + " on background whitelist; not restricted in background");
8162            }
8163            return ActivityManager.APP_START_MODE_NORMAL;
8164        }
8165
8166        // Is this app on the battery whitelist?
8167        if (isOnDeviceIdleWhitelistLocked(uid)) {
8168            if (DEBUG_BACKGROUND_CHECK) {
8169                Slog.i(TAG, "App " + uid + "/" + packageName
8170                        + " on idle whitelist; not restricted in background");
8171            }
8172            return ActivityManager.APP_START_MODE_NORMAL;
8173        }
8174
8175        // None of the service-policy criteria apply, so we apply the common criteria
8176        return appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk);
8177    }
8178
8179    int getAppStartModeLocked(int uid, String packageName, int packageTargetSdk,
8180            int callingPid, boolean alwaysRestrict, boolean disabledOnly) {
8181        UidRecord uidRec = mActiveUids.get(uid);
8182        if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid + " pkg="
8183                + packageName + " rec=" + uidRec + " always=" + alwaysRestrict + " idle="
8184                + (uidRec != null ? uidRec.idle : false));
8185        if (uidRec == null || alwaysRestrict || uidRec.idle) {
8186            boolean ephemeral;
8187            if (uidRec == null) {
8188                ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
8189                        UserHandle.getUserId(uid), packageName);
8190            } else {
8191                ephemeral = uidRec.ephemeral;
8192            }
8193
8194            if (ephemeral) {
8195                // We are hard-core about ephemeral apps not running in the background.
8196                return ActivityManager.APP_START_MODE_DISABLED;
8197            } else {
8198                if (disabledOnly) {
8199                    // The caller is only interested in whether app starts are completely
8200                    // disabled for the given package (that is, it is an instant app).  So
8201                    // we don't need to go further, which is all just seeing if we should
8202                    // apply a "delayed" mode for a regular app.
8203                    return ActivityManager.APP_START_MODE_NORMAL;
8204                }
8205                final int startMode = (alwaysRestrict)
8206                        ? appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk)
8207                        : appServicesRestrictedInBackgroundLocked(uid, packageName,
8208                                packageTargetSdk);
8209                if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid
8210                        + " pkg=" + packageName + " startMode=" + startMode
8211                        + " onwhitelist=" + isOnDeviceIdleWhitelistLocked(uid));
8212                if (startMode == ActivityManager.APP_START_MODE_DELAYED) {
8213                    // This is an old app that has been forced into a "compatible as possible"
8214                    // mode of background check.  To increase compatibility, we will allow other
8215                    // foreground apps to cause its services to start.
8216                    if (callingPid >= 0) {
8217                        ProcessRecord proc;
8218                        synchronized (mPidsSelfLocked) {
8219                            proc = mPidsSelfLocked.get(callingPid);
8220                        }
8221                        if (proc != null && proc.curProcState
8222                                < ActivityManager.PROCESS_STATE_RECEIVER) {
8223                            // Whoever is instigating this is in the foreground, so we will allow it
8224                            // to go through.
8225                            return ActivityManager.APP_START_MODE_NORMAL;
8226                        }
8227                    }
8228                }
8229                return startMode;
8230            }
8231        }
8232        return ActivityManager.APP_START_MODE_NORMAL;
8233    }
8234
8235    boolean isOnDeviceIdleWhitelistLocked(int uid) {
8236        final int appId = UserHandle.getAppId(uid);
8237        return Arrays.binarySearch(mDeviceIdleWhitelist, appId) >= 0
8238                || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0;
8239    }
8240
8241    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
8242        ProviderInfo pi = null;
8243        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
8244        if (cpr != null) {
8245            pi = cpr.info;
8246        } else {
8247            try {
8248                pi = AppGlobals.getPackageManager().resolveContentProvider(
8249                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
8250                        userHandle);
8251            } catch (RemoteException ex) {
8252            }
8253        }
8254        return pi;
8255    }
8256
8257    void grantEphemeralAccessLocked(int userId, Intent intent,
8258            int targetAppId, int ephemeralAppId) {
8259        getPackageManagerInternalLocked().
8260                grantEphemeralAccess(userId, intent, targetAppId, ephemeralAppId);
8261    }
8262
8263    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
8264        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8265        if (targetUris != null) {
8266            return targetUris.get(grantUri);
8267        }
8268        return null;
8269    }
8270
8271    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
8272            String targetPkg, int targetUid, GrantUri grantUri) {
8273        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8274        if (targetUris == null) {
8275            targetUris = Maps.newArrayMap();
8276            mGrantedUriPermissions.put(targetUid, targetUris);
8277        }
8278
8279        UriPermission perm = targetUris.get(grantUri);
8280        if (perm == null) {
8281            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
8282            targetUris.put(grantUri, perm);
8283        }
8284
8285        return perm;
8286    }
8287
8288    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
8289            final int modeFlags) {
8290        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
8291        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
8292                : UriPermission.STRENGTH_OWNED;
8293
8294        // Root gets to do everything.
8295        if (uid == 0) {
8296            return true;
8297        }
8298
8299        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8300        if (perms == null) return false;
8301
8302        // First look for exact match
8303        final UriPermission exactPerm = perms.get(grantUri);
8304        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
8305            return true;
8306        }
8307
8308        // No exact match, look for prefixes
8309        final int N = perms.size();
8310        for (int i = 0; i < N; i++) {
8311            final UriPermission perm = perms.valueAt(i);
8312            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
8313                    && perm.getStrength(modeFlags) >= minStrength) {
8314                return true;
8315            }
8316        }
8317
8318        return false;
8319    }
8320
8321    /**
8322     * @param uri This uri must NOT contain an embedded userId.
8323     * @param userId The userId in which the uri is to be resolved.
8324     */
8325    @Override
8326    public int checkUriPermission(Uri uri, int pid, int uid,
8327            final int modeFlags, int userId, IBinder callerToken) {
8328        enforceNotIsolatedCaller("checkUriPermission");
8329
8330        // Another redirected-binder-call permissions check as in
8331        // {@link checkPermissionWithToken}.
8332        Identity tlsIdentity = sCallerIdentity.get();
8333        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8334            uid = tlsIdentity.uid;
8335            pid = tlsIdentity.pid;
8336        }
8337
8338        // Our own process gets to do everything.
8339        if (pid == MY_PID) {
8340            return PackageManager.PERMISSION_GRANTED;
8341        }
8342        synchronized (this) {
8343            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8344                    ? PackageManager.PERMISSION_GRANTED
8345                    : PackageManager.PERMISSION_DENIED;
8346        }
8347    }
8348
8349    /**
8350     * Check if the targetPkg can be granted permission to access uri by
8351     * the callingUid using the given modeFlags.  Throws a security exception
8352     * if callingUid is not allowed to do this.  Returns the uid of the target
8353     * if the URI permission grant should be performed; returns -1 if it is not
8354     * needed (for example targetPkg already has permission to access the URI).
8355     * If you already know the uid of the target, you can supply it in
8356     * lastTargetUid else set that to -1.
8357     */
8358    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8359            final int modeFlags, int lastTargetUid) {
8360        if (!Intent.isAccessUriMode(modeFlags)) {
8361            return -1;
8362        }
8363
8364        if (targetPkg != null) {
8365            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8366                    "Checking grant " + targetPkg + " permission to " + grantUri);
8367        }
8368
8369        final IPackageManager pm = AppGlobals.getPackageManager();
8370
8371        // If this is not a content: uri, we can't do anything with it.
8372        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8373            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8374                    "Can't grant URI permission for non-content URI: " + grantUri);
8375            return -1;
8376        }
8377
8378        final String authority = grantUri.uri.getAuthority();
8379        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8380                MATCH_DEBUG_TRIAGED_MISSING);
8381        if (pi == null) {
8382            Slog.w(TAG, "No content provider found for permission check: " +
8383                    grantUri.uri.toSafeString());
8384            return -1;
8385        }
8386
8387        int targetUid = lastTargetUid;
8388        if (targetUid < 0 && targetPkg != null) {
8389            try {
8390                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8391                        UserHandle.getUserId(callingUid));
8392                if (targetUid < 0) {
8393                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8394                            "Can't grant URI permission no uid for: " + targetPkg);
8395                    return -1;
8396                }
8397            } catch (RemoteException ex) {
8398                return -1;
8399            }
8400        }
8401
8402        // If we're extending a persistable grant, then we always need to create
8403        // the grant data structure so that take/release APIs work
8404        if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
8405            return targetUid;
8406        }
8407
8408        if (targetUid >= 0) {
8409            // First...  does the target actually need this permission?
8410            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8411                // No need to grant the target this permission.
8412                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8413                        "Target " + targetPkg + " already has full permission to " + grantUri);
8414                return -1;
8415            }
8416        } else {
8417            // First...  there is no target package, so can anyone access it?
8418            boolean allowed = pi.exported;
8419            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8420                if (pi.readPermission != null) {
8421                    allowed = false;
8422                }
8423            }
8424            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8425                if (pi.writePermission != null) {
8426                    allowed = false;
8427                }
8428            }
8429            if (allowed) {
8430                return -1;
8431            }
8432        }
8433
8434        /* There is a special cross user grant if:
8435         * - The target is on another user.
8436         * - Apps on the current user can access the uri without any uid permissions.
8437         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8438         * grant uri permissions.
8439         */
8440        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8441                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8442                modeFlags, false /*without considering the uid permissions*/);
8443
8444        // Second...  is the provider allowing granting of URI permissions?
8445        if (!specialCrossUserGrant) {
8446            if (!pi.grantUriPermissions) {
8447                throw new SecurityException("Provider " + pi.packageName
8448                        + "/" + pi.name
8449                        + " does not allow granting of Uri permissions (uri "
8450                        + grantUri + ")");
8451            }
8452            if (pi.uriPermissionPatterns != null) {
8453                final int N = pi.uriPermissionPatterns.length;
8454                boolean allowed = false;
8455                for (int i=0; i<N; i++) {
8456                    if (pi.uriPermissionPatterns[i] != null
8457                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8458                        allowed = true;
8459                        break;
8460                    }
8461                }
8462                if (!allowed) {
8463                    throw new SecurityException("Provider " + pi.packageName
8464                            + "/" + pi.name
8465                            + " does not allow granting of permission to path of Uri "
8466                            + grantUri);
8467                }
8468            }
8469        }
8470
8471        // Third...  does the caller itself have permission to access
8472        // this uri?
8473        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
8474            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8475                // Require they hold a strong enough Uri permission
8476                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8477                    throw new SecurityException("Uid " + callingUid
8478                            + " does not have permission to uri " + grantUri);
8479                }
8480            }
8481        }
8482        return targetUid;
8483    }
8484
8485    /**
8486     * @param uri This uri must NOT contain an embedded userId.
8487     * @param userId The userId in which the uri is to be resolved.
8488     */
8489    @Override
8490    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8491            final int modeFlags, int userId) {
8492        enforceNotIsolatedCaller("checkGrantUriPermission");
8493        synchronized(this) {
8494            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8495                    new GrantUri(userId, uri, false), modeFlags, -1);
8496        }
8497    }
8498
8499    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8500            final int modeFlags, UriPermissionOwner owner) {
8501        if (!Intent.isAccessUriMode(modeFlags)) {
8502            return;
8503        }
8504
8505        // So here we are: the caller has the assumed permission
8506        // to the uri, and the target doesn't.  Let's now give this to
8507        // the target.
8508
8509        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8510                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8511
8512        final String authority = grantUri.uri.getAuthority();
8513        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8514                MATCH_DEBUG_TRIAGED_MISSING);
8515        if (pi == null) {
8516            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8517            return;
8518        }
8519
8520        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8521            grantUri.prefix = true;
8522        }
8523        final UriPermission perm = findOrCreateUriPermissionLocked(
8524                pi.packageName, targetPkg, targetUid, grantUri);
8525        perm.grantModes(modeFlags, owner);
8526    }
8527
8528    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8529            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8530        if (targetPkg == null) {
8531            throw new NullPointerException("targetPkg");
8532        }
8533        int targetUid;
8534        final IPackageManager pm = AppGlobals.getPackageManager();
8535        try {
8536            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8537        } catch (RemoteException ex) {
8538            return;
8539        }
8540
8541        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8542                targetUid);
8543        if (targetUid < 0) {
8544            return;
8545        }
8546
8547        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8548                owner);
8549    }
8550
8551    static class NeededUriGrants extends ArrayList<GrantUri> {
8552        final String targetPkg;
8553        final int targetUid;
8554        final int flags;
8555
8556        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8557            this.targetPkg = targetPkg;
8558            this.targetUid = targetUid;
8559            this.flags = flags;
8560        }
8561    }
8562
8563    /**
8564     * Like checkGrantUriPermissionLocked, but takes an Intent.
8565     */
8566    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8567            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8568        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8569                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8570                + " clip=" + (intent != null ? intent.getClipData() : null)
8571                + " from " + intent + "; flags=0x"
8572                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8573
8574        if (targetPkg == null) {
8575            throw new NullPointerException("targetPkg");
8576        }
8577
8578        if (intent == null) {
8579            return null;
8580        }
8581        Uri data = intent.getData();
8582        ClipData clip = intent.getClipData();
8583        if (data == null && clip == null) {
8584            return null;
8585        }
8586        // Default userId for uris in the intent (if they don't specify it themselves)
8587        int contentUserHint = intent.getContentUserHint();
8588        if (contentUserHint == UserHandle.USER_CURRENT) {
8589            contentUserHint = UserHandle.getUserId(callingUid);
8590        }
8591        final IPackageManager pm = AppGlobals.getPackageManager();
8592        int targetUid;
8593        if (needed != null) {
8594            targetUid = needed.targetUid;
8595        } else {
8596            try {
8597                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8598                        targetUserId);
8599            } catch (RemoteException ex) {
8600                return null;
8601            }
8602            if (targetUid < 0) {
8603                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8604                        "Can't grant URI permission no uid for: " + targetPkg
8605                        + " on user " + targetUserId);
8606                return null;
8607            }
8608        }
8609        if (data != null) {
8610            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8611            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8612                    targetUid);
8613            if (targetUid > 0) {
8614                if (needed == null) {
8615                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8616                }
8617                needed.add(grantUri);
8618            }
8619        }
8620        if (clip != null) {
8621            for (int i=0; i<clip.getItemCount(); i++) {
8622                Uri uri = clip.getItemAt(i).getUri();
8623                if (uri != null) {
8624                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8625                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8626                            targetUid);
8627                    if (targetUid > 0) {
8628                        if (needed == null) {
8629                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8630                        }
8631                        needed.add(grantUri);
8632                    }
8633                } else {
8634                    Intent clipIntent = clip.getItemAt(i).getIntent();
8635                    if (clipIntent != null) {
8636                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8637                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8638                        if (newNeeded != null) {
8639                            needed = newNeeded;
8640                        }
8641                    }
8642                }
8643            }
8644        }
8645
8646        return needed;
8647    }
8648
8649    /**
8650     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8651     */
8652    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8653            UriPermissionOwner owner) {
8654        if (needed != null) {
8655            for (int i=0; i<needed.size(); i++) {
8656                GrantUri grantUri = needed.get(i);
8657                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8658                        grantUri, needed.flags, owner);
8659            }
8660        }
8661    }
8662
8663    void grantUriPermissionFromIntentLocked(int callingUid,
8664            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8665        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8666                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8667        if (needed == null) {
8668            return;
8669        }
8670
8671        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8672    }
8673
8674    /**
8675     * @param uri This uri must NOT contain an embedded userId.
8676     * @param userId The userId in which the uri is to be resolved.
8677     */
8678    @Override
8679    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8680            final int modeFlags, int userId) {
8681        enforceNotIsolatedCaller("grantUriPermission");
8682        GrantUri grantUri = new GrantUri(userId, uri, false);
8683        synchronized(this) {
8684            final ProcessRecord r = getRecordForAppLocked(caller);
8685            if (r == null) {
8686                throw new SecurityException("Unable to find app for caller "
8687                        + caller
8688                        + " when granting permission to uri " + grantUri);
8689            }
8690            if (targetPkg == null) {
8691                throw new IllegalArgumentException("null target");
8692            }
8693            if (grantUri == null) {
8694                throw new IllegalArgumentException("null uri");
8695            }
8696
8697            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8698                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8699                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8700                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8701
8702            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8703                    UserHandle.getUserId(r.uid));
8704        }
8705    }
8706
8707    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8708        if (perm.modeFlags == 0) {
8709            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8710                    perm.targetUid);
8711            if (perms != null) {
8712                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8713                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8714
8715                perms.remove(perm.uri);
8716                if (perms.isEmpty()) {
8717                    mGrantedUriPermissions.remove(perm.targetUid);
8718                }
8719            }
8720        }
8721    }
8722
8723    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8724        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8725                "Revoking all granted permissions to " + grantUri);
8726
8727        final IPackageManager pm = AppGlobals.getPackageManager();
8728        final String authority = grantUri.uri.getAuthority();
8729        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8730                MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8731        if (pi == null) {
8732            Slog.w(TAG, "No content provider found for permission revoke: "
8733                    + grantUri.toSafeString());
8734            return;
8735        }
8736
8737        // Does the caller have this permission on the URI?
8738        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8739            // If they don't have direct access to the URI, then revoke any
8740            // ownerless URI permissions that have been granted to them.
8741            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8742            if (perms != null) {
8743                boolean persistChanged = false;
8744                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8745                    final UriPermission perm = it.next();
8746                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8747                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8748                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8749                                "Revoking non-owned " + perm.targetUid
8750                                + " permission to " + perm.uri);
8751                        persistChanged |= perm.revokeModes(
8752                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8753                        if (perm.modeFlags == 0) {
8754                            it.remove();
8755                        }
8756                    }
8757                }
8758                if (perms.isEmpty()) {
8759                    mGrantedUriPermissions.remove(callingUid);
8760                }
8761                if (persistChanged) {
8762                    schedulePersistUriGrants();
8763                }
8764            }
8765            return;
8766        }
8767
8768        boolean persistChanged = false;
8769
8770        // Go through all of the permissions and remove any that match.
8771        int N = mGrantedUriPermissions.size();
8772        for (int i = 0; i < N; i++) {
8773            final int targetUid = mGrantedUriPermissions.keyAt(i);
8774            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8775
8776            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8777                final UriPermission perm = it.next();
8778                if (perm.uri.sourceUserId == grantUri.sourceUserId
8779                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8780                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8781                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8782                    persistChanged |= perm.revokeModes(
8783                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8784                    if (perm.modeFlags == 0) {
8785                        it.remove();
8786                    }
8787                }
8788            }
8789
8790            if (perms.isEmpty()) {
8791                mGrantedUriPermissions.remove(targetUid);
8792                N--;
8793                i--;
8794            }
8795        }
8796
8797        if (persistChanged) {
8798            schedulePersistUriGrants();
8799        }
8800    }
8801
8802    /**
8803     * @param uri This uri must NOT contain an embedded userId.
8804     * @param userId The userId in which the uri is to be resolved.
8805     */
8806    @Override
8807    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8808            int userId) {
8809        enforceNotIsolatedCaller("revokeUriPermission");
8810        synchronized(this) {
8811            final ProcessRecord r = getRecordForAppLocked(caller);
8812            if (r == null) {
8813                throw new SecurityException("Unable to find app for caller "
8814                        + caller
8815                        + " when revoking permission to uri " + uri);
8816            }
8817            if (uri == null) {
8818                Slog.w(TAG, "revokeUriPermission: null uri");
8819                return;
8820            }
8821
8822            if (!Intent.isAccessUriMode(modeFlags)) {
8823                return;
8824            }
8825
8826            final String authority = uri.getAuthority();
8827            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8828                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8829            if (pi == null) {
8830                Slog.w(TAG, "No content provider found for permission revoke: "
8831                        + uri.toSafeString());
8832                return;
8833            }
8834
8835            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8836        }
8837    }
8838
8839    /**
8840     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8841     * given package.
8842     *
8843     * @param packageName Package name to match, or {@code null} to apply to all
8844     *            packages.
8845     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8846     *            to all users.
8847     * @param persistable If persistable grants should be removed.
8848     */
8849    private void removeUriPermissionsForPackageLocked(
8850            String packageName, int userHandle, boolean persistable) {
8851        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8852            throw new IllegalArgumentException("Must narrow by either package or user");
8853        }
8854
8855        boolean persistChanged = false;
8856
8857        int N = mGrantedUriPermissions.size();
8858        for (int i = 0; i < N; i++) {
8859            final int targetUid = mGrantedUriPermissions.keyAt(i);
8860            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8861
8862            // Only inspect grants matching user
8863            if (userHandle == UserHandle.USER_ALL
8864                    || userHandle == UserHandle.getUserId(targetUid)) {
8865                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8866                    final UriPermission perm = it.next();
8867
8868                    // Only inspect grants matching package
8869                    if (packageName == null || perm.sourcePkg.equals(packageName)
8870                            || perm.targetPkg.equals(packageName)) {
8871                        // Hacky solution as part of fixing a security bug; ignore
8872                        // grants associated with DownloadManager so we don't have
8873                        // to immediately launch it to regrant the permissions
8874                        if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
8875                                && !persistable) continue;
8876
8877                        persistChanged |= perm.revokeModes(persistable
8878                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8879
8880                        // Only remove when no modes remain; any persisted grants
8881                        // will keep this alive.
8882                        if (perm.modeFlags == 0) {
8883                            it.remove();
8884                        }
8885                    }
8886                }
8887
8888                if (perms.isEmpty()) {
8889                    mGrantedUriPermissions.remove(targetUid);
8890                    N--;
8891                    i--;
8892                }
8893            }
8894        }
8895
8896        if (persistChanged) {
8897            schedulePersistUriGrants();
8898        }
8899    }
8900
8901    @Override
8902    public IBinder newUriPermissionOwner(String name) {
8903        enforceNotIsolatedCaller("newUriPermissionOwner");
8904        synchronized(this) {
8905            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8906            return owner.getExternalTokenLocked();
8907        }
8908    }
8909
8910    @Override
8911    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8912        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8913        synchronized(this) {
8914            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8915            if (r == null) {
8916                throw new IllegalArgumentException("Activity does not exist; token="
8917                        + activityToken);
8918            }
8919            return r.getUriPermissionsLocked().getExternalTokenLocked();
8920        }
8921    }
8922    /**
8923     * @param uri This uri must NOT contain an embedded userId.
8924     * @param sourceUserId The userId in which the uri is to be resolved.
8925     * @param targetUserId The userId of the app that receives the grant.
8926     */
8927    @Override
8928    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8929            final int modeFlags, int sourceUserId, int targetUserId) {
8930        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8931                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8932                "grantUriPermissionFromOwner", null);
8933        synchronized(this) {
8934            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8935            if (owner == null) {
8936                throw new IllegalArgumentException("Unknown owner: " + token);
8937            }
8938            if (fromUid != Binder.getCallingUid()) {
8939                if (Binder.getCallingUid() != Process.myUid()) {
8940                    // Only system code can grant URI permissions on behalf
8941                    // of other users.
8942                    throw new SecurityException("nice try");
8943                }
8944            }
8945            if (targetPkg == null) {
8946                throw new IllegalArgumentException("null target");
8947            }
8948            if (uri == null) {
8949                throw new IllegalArgumentException("null uri");
8950            }
8951
8952            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8953                    modeFlags, owner, targetUserId);
8954        }
8955    }
8956
8957    /**
8958     * @param uri This uri must NOT contain an embedded userId.
8959     * @param userId The userId in which the uri is to be resolved.
8960     */
8961    @Override
8962    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8963        synchronized(this) {
8964            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8965            if (owner == null) {
8966                throw new IllegalArgumentException("Unknown owner: " + token);
8967            }
8968
8969            if (uri == null) {
8970                owner.removeUriPermissionsLocked(mode);
8971            } else {
8972                final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
8973                owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
8974            }
8975        }
8976    }
8977
8978    private void schedulePersistUriGrants() {
8979        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8980            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8981                    10 * DateUtils.SECOND_IN_MILLIS);
8982        }
8983    }
8984
8985    private void writeGrantedUriPermissions() {
8986        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8987
8988        // Snapshot permissions so we can persist without lock
8989        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8990        synchronized (this) {
8991            final int size = mGrantedUriPermissions.size();
8992            for (int i = 0; i < size; i++) {
8993                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8994                for (UriPermission perm : perms.values()) {
8995                    if (perm.persistedModeFlags != 0) {
8996                        persist.add(perm.snapshot());
8997                    }
8998                }
8999            }
9000        }
9001
9002        FileOutputStream fos = null;
9003        try {
9004            fos = mGrantFile.startWrite();
9005
9006            XmlSerializer out = new FastXmlSerializer();
9007            out.setOutput(fos, StandardCharsets.UTF_8.name());
9008            out.startDocument(null, true);
9009            out.startTag(null, TAG_URI_GRANTS);
9010            for (UriPermission.Snapshot perm : persist) {
9011                out.startTag(null, TAG_URI_GRANT);
9012                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
9013                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
9014                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
9015                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
9016                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
9017                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
9018                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
9019                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
9020                out.endTag(null, TAG_URI_GRANT);
9021            }
9022            out.endTag(null, TAG_URI_GRANTS);
9023            out.endDocument();
9024
9025            mGrantFile.finishWrite(fos);
9026        } catch (IOException e) {
9027            if (fos != null) {
9028                mGrantFile.failWrite(fos);
9029            }
9030        }
9031    }
9032
9033    private void readGrantedUriPermissionsLocked() {
9034        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
9035
9036        final long now = System.currentTimeMillis();
9037
9038        FileInputStream fis = null;
9039        try {
9040            fis = mGrantFile.openRead();
9041            final XmlPullParser in = Xml.newPullParser();
9042            in.setInput(fis, StandardCharsets.UTF_8.name());
9043
9044            int type;
9045            while ((type = in.next()) != END_DOCUMENT) {
9046                final String tag = in.getName();
9047                if (type == START_TAG) {
9048                    if (TAG_URI_GRANT.equals(tag)) {
9049                        final int sourceUserId;
9050                        final int targetUserId;
9051                        final int userHandle = readIntAttribute(in,
9052                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
9053                        if (userHandle != UserHandle.USER_NULL) {
9054                            // For backwards compatibility.
9055                            sourceUserId = userHandle;
9056                            targetUserId = userHandle;
9057                        } else {
9058                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
9059                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
9060                        }
9061                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
9062                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
9063                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
9064                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
9065                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
9066                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
9067
9068                        // Sanity check that provider still belongs to source package
9069                        // Both direct boot aware and unaware packages are fine as we
9070                        // will do filtering at query time to avoid multiple parsing.
9071                        final ProviderInfo pi = getProviderInfoLocked(
9072                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
9073                                        | MATCH_DIRECT_BOOT_UNAWARE);
9074                        if (pi != null && sourcePkg.equals(pi.packageName)) {
9075                            int targetUid = -1;
9076                            try {
9077                                targetUid = AppGlobals.getPackageManager().getPackageUid(
9078                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
9079                            } catch (RemoteException e) {
9080                            }
9081                            if (targetUid != -1) {
9082                                final UriPermission perm = findOrCreateUriPermissionLocked(
9083                                        sourcePkg, targetPkg, targetUid,
9084                                        new GrantUri(sourceUserId, uri, prefix));
9085                                perm.initPersistedModes(modeFlags, createdTime);
9086                            }
9087                        } else {
9088                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
9089                                    + " but instead found " + pi);
9090                        }
9091                    }
9092                }
9093            }
9094        } catch (FileNotFoundException e) {
9095            // Missing grants is okay
9096        } catch (IOException e) {
9097            Slog.wtf(TAG, "Failed reading Uri grants", e);
9098        } catch (XmlPullParserException e) {
9099            Slog.wtf(TAG, "Failed reading Uri grants", e);
9100        } finally {
9101            IoUtils.closeQuietly(fis);
9102        }
9103    }
9104
9105    /**
9106     * @param uri This uri must NOT contain an embedded userId.
9107     * @param userId The userId in which the uri is to be resolved.
9108     */
9109    @Override
9110    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9111        enforceNotIsolatedCaller("takePersistableUriPermission");
9112
9113        Preconditions.checkFlagsArgument(modeFlags,
9114                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9115
9116        synchronized (this) {
9117            final int callingUid = Binder.getCallingUid();
9118            boolean persistChanged = false;
9119            GrantUri grantUri = new GrantUri(userId, uri, false);
9120
9121            UriPermission exactPerm = findUriPermissionLocked(callingUid,
9122                    new GrantUri(userId, uri, false));
9123            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9124                    new GrantUri(userId, uri, true));
9125
9126            final boolean exactValid = (exactPerm != null)
9127                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
9128            final boolean prefixValid = (prefixPerm != null)
9129                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
9130
9131            if (!(exactValid || prefixValid)) {
9132                throw new SecurityException("No persistable permission grants found for UID "
9133                        + callingUid + " and Uri " + grantUri.toSafeString());
9134            }
9135
9136            if (exactValid) {
9137                persistChanged |= exactPerm.takePersistableModes(modeFlags);
9138            }
9139            if (prefixValid) {
9140                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
9141            }
9142
9143            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
9144
9145            if (persistChanged) {
9146                schedulePersistUriGrants();
9147            }
9148        }
9149    }
9150
9151    /**
9152     * @param uri This uri must NOT contain an embedded userId.
9153     * @param userId The userId in which the uri is to be resolved.
9154     */
9155    @Override
9156    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9157        enforceNotIsolatedCaller("releasePersistableUriPermission");
9158
9159        Preconditions.checkFlagsArgument(modeFlags,
9160                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9161
9162        synchronized (this) {
9163            final int callingUid = Binder.getCallingUid();
9164            boolean persistChanged = false;
9165
9166            UriPermission exactPerm = findUriPermissionLocked(callingUid,
9167                    new GrantUri(userId, uri, false));
9168            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9169                    new GrantUri(userId, uri, true));
9170            if (exactPerm == null && prefixPerm == null) {
9171                throw new SecurityException("No permission grants found for UID " + callingUid
9172                        + " and Uri " + uri.toSafeString());
9173            }
9174
9175            if (exactPerm != null) {
9176                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
9177                removeUriPermissionIfNeededLocked(exactPerm);
9178            }
9179            if (prefixPerm != null) {
9180                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
9181                removeUriPermissionIfNeededLocked(prefixPerm);
9182            }
9183
9184            if (persistChanged) {
9185                schedulePersistUriGrants();
9186            }
9187        }
9188    }
9189
9190    /**
9191     * Prune any older {@link UriPermission} for the given UID until outstanding
9192     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
9193     *
9194     * @return if any mutations occured that require persisting.
9195     */
9196    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
9197        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
9198        if (perms == null) return false;
9199        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
9200
9201        final ArrayList<UriPermission> persisted = Lists.newArrayList();
9202        for (UriPermission perm : perms.values()) {
9203            if (perm.persistedModeFlags != 0) {
9204                persisted.add(perm);
9205            }
9206        }
9207
9208        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
9209        if (trimCount <= 0) return false;
9210
9211        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
9212        for (int i = 0; i < trimCount; i++) {
9213            final UriPermission perm = persisted.get(i);
9214
9215            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9216                    "Trimming grant created at " + perm.persistedCreateTime);
9217
9218            perm.releasePersistableModes(~0);
9219            removeUriPermissionIfNeededLocked(perm);
9220        }
9221
9222        return true;
9223    }
9224
9225    @Override
9226    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
9227            String packageName, boolean incoming) {
9228        enforceNotIsolatedCaller("getPersistedUriPermissions");
9229        Preconditions.checkNotNull(packageName, "packageName");
9230
9231        final int callingUid = Binder.getCallingUid();
9232        final int callingUserId = UserHandle.getUserId(callingUid);
9233        final IPackageManager pm = AppGlobals.getPackageManager();
9234        try {
9235            final int packageUid = pm.getPackageUid(packageName,
9236                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
9237            if (packageUid != callingUid) {
9238                throw new SecurityException(
9239                        "Package " + packageName + " does not belong to calling UID " + callingUid);
9240            }
9241        } catch (RemoteException e) {
9242            throw new SecurityException("Failed to verify package name ownership");
9243        }
9244
9245        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9246        synchronized (this) {
9247            if (incoming) {
9248                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9249                        callingUid);
9250                if (perms == null) {
9251                    Slog.w(TAG, "No permission grants found for " + packageName);
9252                } else {
9253                    for (UriPermission perm : perms.values()) {
9254                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
9255                            result.add(perm.buildPersistedPublicApiObject());
9256                        }
9257                    }
9258                }
9259            } else {
9260                final int size = mGrantedUriPermissions.size();
9261                for (int i = 0; i < size; i++) {
9262                    final ArrayMap<GrantUri, UriPermission> perms =
9263                            mGrantedUriPermissions.valueAt(i);
9264                    for (UriPermission perm : perms.values()) {
9265                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
9266                            result.add(perm.buildPersistedPublicApiObject());
9267                        }
9268                    }
9269                }
9270            }
9271        }
9272        return new ParceledListSlice<android.content.UriPermission>(result);
9273    }
9274
9275    @Override
9276    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
9277            String packageName, int userId) {
9278        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
9279                "getGrantedUriPermissions");
9280
9281        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9282        synchronized (this) {
9283            final int size = mGrantedUriPermissions.size();
9284            for (int i = 0; i < size; i++) {
9285                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9286                for (UriPermission perm : perms.values()) {
9287                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
9288                            && perm.persistedModeFlags != 0) {
9289                        result.add(perm.buildPersistedPublicApiObject());
9290                    }
9291                }
9292            }
9293        }
9294        return new ParceledListSlice<android.content.UriPermission>(result);
9295    }
9296
9297    @Override
9298    public void clearGrantedUriPermissions(String packageName, int userId) {
9299        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
9300                "clearGrantedUriPermissions");
9301        removeUriPermissionsForPackageLocked(packageName, userId, true);
9302    }
9303
9304    @Override
9305    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
9306        synchronized (this) {
9307            ProcessRecord app =
9308                who != null ? getRecordForAppLocked(who) : null;
9309            if (app == null) return;
9310
9311            Message msg = Message.obtain();
9312            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
9313            msg.obj = app;
9314            msg.arg1 = waiting ? 1 : 0;
9315            mUiHandler.sendMessage(msg);
9316        }
9317    }
9318
9319    @Override
9320    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9321        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9322        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9323        outInfo.availMem = Process.getFreeMemory();
9324        outInfo.totalMem = Process.getTotalMemory();
9325        outInfo.threshold = homeAppMem;
9326        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9327        outInfo.hiddenAppThreshold = cachedAppMem;
9328        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9329                ProcessList.SERVICE_ADJ);
9330        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9331                ProcessList.VISIBLE_APP_ADJ);
9332        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9333                ProcessList.FOREGROUND_APP_ADJ);
9334    }
9335
9336    // =========================================================
9337    // TASK MANAGEMENT
9338    // =========================================================
9339
9340    @Override
9341    public List<IBinder> getAppTasks(String callingPackage) {
9342        int callingUid = Binder.getCallingUid();
9343        long ident = Binder.clearCallingIdentity();
9344
9345        synchronized(this) {
9346            ArrayList<IBinder> list = new ArrayList<IBinder>();
9347            try {
9348                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9349
9350                final int N = mRecentTasks.size();
9351                for (int i = 0; i < N; i++) {
9352                    TaskRecord tr = mRecentTasks.get(i);
9353                    // Skip tasks that do not match the caller.  We don't need to verify
9354                    // callingPackage, because we are also limiting to callingUid and know
9355                    // that will limit to the correct security sandbox.
9356                    if (tr.effectiveUid != callingUid) {
9357                        continue;
9358                    }
9359                    Intent intent = tr.getBaseIntent();
9360                    if (intent == null ||
9361                            !callingPackage.equals(intent.getComponent().getPackageName())) {
9362                        continue;
9363                    }
9364                    ActivityManager.RecentTaskInfo taskInfo =
9365                            createRecentTaskInfoFromTaskRecord(tr);
9366                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9367                    list.add(taskImpl.asBinder());
9368                }
9369            } finally {
9370                Binder.restoreCallingIdentity(ident);
9371            }
9372            return list;
9373        }
9374    }
9375
9376    @Override
9377    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9378        final int callingUid = Binder.getCallingUid();
9379        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9380
9381        synchronized(this) {
9382            if (DEBUG_ALL) Slog.v(
9383                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9384
9385            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9386                    callingUid);
9387
9388            // TODO: Improve with MRU list from all ActivityStacks.
9389            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9390        }
9391
9392        return list;
9393    }
9394
9395    /**
9396     * Creates a new RecentTaskInfo from a TaskRecord.
9397     */
9398    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9399        // Update the task description to reflect any changes in the task stack
9400        tr.updateTaskDescription();
9401
9402        // Compose the recent task info
9403        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9404        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9405        rti.persistentId = tr.taskId;
9406        rti.baseIntent = new Intent(tr.getBaseIntent());
9407        rti.origActivity = tr.origActivity;
9408        rti.realActivity = tr.realActivity;
9409        rti.description = tr.lastDescription;
9410        rti.stackId = tr.getStackId();
9411        rti.userId = tr.userId;
9412        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9413        rti.firstActiveTime = tr.firstActiveTime;
9414        rti.lastActiveTime = tr.lastActiveTime;
9415        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9416        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9417        rti.numActivities = 0;
9418        if (tr.mBounds != null) {
9419            rti.bounds = new Rect(tr.mBounds);
9420        }
9421        rti.supportsSplitScreenMultiWindow = tr.supportsSplitScreen();
9422        rti.resizeMode = tr.mResizeMode;
9423
9424        ActivityRecord base = null;
9425        ActivityRecord top = null;
9426        ActivityRecord tmp;
9427
9428        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9429            tmp = tr.mActivities.get(i);
9430            if (tmp.finishing) {
9431                continue;
9432            }
9433            base = tmp;
9434            if (top == null || (top.state == ActivityState.INITIALIZING)) {
9435                top = base;
9436            }
9437            rti.numActivities++;
9438        }
9439
9440        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9441        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9442
9443        return rti;
9444    }
9445
9446    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9447        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9448                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9449        if (!allowed) {
9450            if (checkPermission(android.Manifest.permission.GET_TASKS,
9451                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9452                // Temporary compatibility: some existing apps on the system image may
9453                // still be requesting the old permission and not switched to the new
9454                // one; if so, we'll still allow them full access.  This means we need
9455                // to see if they are holding the old permission and are a system app.
9456                try {
9457                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9458                        allowed = true;
9459                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9460                                + " is using old GET_TASKS but privileged; allowing");
9461                    }
9462                } catch (RemoteException e) {
9463                }
9464            }
9465        }
9466        if (!allowed) {
9467            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9468                    + " does not hold REAL_GET_TASKS; limiting output");
9469        }
9470        return allowed;
9471    }
9472
9473    @Override
9474    public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9475            int userId) {
9476        final int callingUid = Binder.getCallingUid();
9477        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9478                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9479
9480        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9481        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9482        synchronized (this) {
9483            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9484                    callingUid);
9485            final boolean detailed = checkCallingPermission(
9486                    android.Manifest.permission.GET_DETAILED_TASKS)
9487                    == PackageManager.PERMISSION_GRANTED;
9488
9489            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9490                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9491                return ParceledListSlice.emptyList();
9492            }
9493            mRecentTasks.loadUserRecentsLocked(userId);
9494
9495            final int recentsCount = mRecentTasks.size();
9496            ArrayList<ActivityManager.RecentTaskInfo> res =
9497                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9498
9499            final Set<Integer> includedUsers;
9500            if (includeProfiles) {
9501                includedUsers = mUserController.getProfileIds(userId);
9502            } else {
9503                includedUsers = new HashSet<>();
9504            }
9505            includedUsers.add(Integer.valueOf(userId));
9506
9507            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9508                TaskRecord tr = mRecentTasks.get(i);
9509                // Only add calling user or related users recent tasks
9510                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9511                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9512                    continue;
9513                }
9514
9515                if (tr.realActivitySuspended) {
9516                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9517                    continue;
9518                }
9519
9520                // Return the entry if desired by the caller.  We always return
9521                // the first entry, because callers always expect this to be the
9522                // foreground app.  We may filter others if the caller has
9523                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9524                // we should exclude the entry.
9525
9526                if (i == 0
9527                        || withExcluded
9528                        || (tr.intent == null)
9529                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9530                                == 0)) {
9531                    if (!allowed) {
9532                        // If the caller doesn't have the GET_TASKS permission, then only
9533                        // allow them to see a small subset of tasks -- their own and home.
9534                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9535                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9536                            continue;
9537                        }
9538                    }
9539                    final ActivityStack stack = tr.getStack();
9540                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS) != 0) {
9541                        if (stack != null && stack.isHomeOrRecentsStack()) {
9542                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9543                                    "Skipping, home or recents stack task: " + tr);
9544                            continue;
9545                        }
9546                    }
9547                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9548                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9549                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9550                                    "Skipping, top task in docked stack: " + tr);
9551                            continue;
9552                        }
9553                    }
9554                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9555                        if (stack != null && stack.isPinnedStack()) {
9556                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9557                                    "Skipping, pinned stack task: " + tr);
9558                            continue;
9559                        }
9560                    }
9561                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9562                        // Don't include auto remove tasks that are finished or finishing.
9563                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9564                                "Skipping, auto-remove without activity: " + tr);
9565                        continue;
9566                    }
9567                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9568                            && !tr.isAvailable) {
9569                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9570                                "Skipping, unavail real act: " + tr);
9571                        continue;
9572                    }
9573
9574                    if (!tr.mUserSetupComplete) {
9575                        // Don't include task launched while user is not done setting-up.
9576                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9577                                "Skipping, user setup not complete: " + tr);
9578                        continue;
9579                    }
9580
9581                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9582                    if (!detailed) {
9583                        rti.baseIntent.replaceExtras((Bundle)null);
9584                    }
9585
9586                    res.add(rti);
9587                    maxNum--;
9588                }
9589            }
9590            return new ParceledListSlice<>(res);
9591        }
9592    }
9593
9594    @Override
9595    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9596        synchronized (this) {
9597            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9598                    "getTaskThumbnail()");
9599            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9600                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9601            if (tr != null) {
9602                return tr.getTaskThumbnailLocked();
9603            }
9604        }
9605        return null;
9606    }
9607
9608    @Override
9609    public ActivityManager.TaskDescription getTaskDescription(int id) {
9610        synchronized (this) {
9611            enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9612                    "getTaskDescription()");
9613            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9614                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9615            if (tr != null) {
9616                return tr.lastTaskDescription;
9617            }
9618        }
9619        return null;
9620    }
9621
9622    @Override
9623    public int addAppTask(IBinder activityToken, Intent intent,
9624            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9625        final int callingUid = Binder.getCallingUid();
9626        final long callingIdent = Binder.clearCallingIdentity();
9627
9628        try {
9629            synchronized (this) {
9630                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9631                if (r == null) {
9632                    throw new IllegalArgumentException("Activity does not exist; token="
9633                            + activityToken);
9634                }
9635                ComponentName comp = intent.getComponent();
9636                if (comp == null) {
9637                    throw new IllegalArgumentException("Intent " + intent
9638                            + " must specify explicit component");
9639                }
9640                if (thumbnail.getWidth() != mThumbnailWidth
9641                        || thumbnail.getHeight() != mThumbnailHeight) {
9642                    throw new IllegalArgumentException("Bad thumbnail size: got "
9643                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9644                            + mThumbnailWidth + "x" + mThumbnailHeight);
9645                }
9646                if (intent.getSelector() != null) {
9647                    intent.setSelector(null);
9648                }
9649                if (intent.getSourceBounds() != null) {
9650                    intent.setSourceBounds(null);
9651                }
9652                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9653                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9654                        // The caller has added this as an auto-remove task...  that makes no
9655                        // sense, so turn off auto-remove.
9656                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9657                    }
9658                }
9659                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9660                    mLastAddedTaskActivity = null;
9661                }
9662                ActivityInfo ainfo = mLastAddedTaskActivity;
9663                if (ainfo == null) {
9664                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9665                            comp, 0, UserHandle.getUserId(callingUid));
9666                    if (ainfo.applicationInfo.uid != callingUid) {
9667                        throw new SecurityException(
9668                                "Can't add task for another application: target uid="
9669                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9670                    }
9671                }
9672
9673                TaskRecord task = new TaskRecord(this,
9674                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9675                        ainfo, intent, description, new TaskThumbnailInfo());
9676
9677                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9678                if (trimIdx >= 0) {
9679                    // If this would have caused a trim, then we'll abort because that
9680                    // means it would be added at the end of the list but then just removed.
9681                    return INVALID_TASK_ID;
9682                }
9683
9684                final int N = mRecentTasks.size();
9685                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9686                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9687                    tr.removedFromRecents();
9688                }
9689
9690                task.inRecents = true;
9691                mRecentTasks.add(task);
9692                r.getStack().addTask(task, false, "addAppTask");
9693
9694                task.setLastThumbnailLocked(thumbnail);
9695                task.freeLastThumbnail();
9696                return task.taskId;
9697            }
9698        } finally {
9699            Binder.restoreCallingIdentity(callingIdent);
9700        }
9701    }
9702
9703    @Override
9704    public Point getAppTaskThumbnailSize() {
9705        synchronized (this) {
9706            return new Point(mThumbnailWidth,  mThumbnailHeight);
9707        }
9708    }
9709
9710    @Override
9711    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9712        synchronized (this) {
9713            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9714            if (r != null) {
9715                r.setTaskDescription(td);
9716                r.task.updateTaskDescription();
9717                mTaskChangeNotificationController.notifyTaskDescriptionChanged(r.task.taskId, td);
9718            }
9719        }
9720    }
9721
9722    @Override
9723    public void setTaskResizeable(int taskId, int resizeableMode) {
9724        synchronized (this) {
9725            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9726                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9727            if (task == null) {
9728                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9729                return;
9730            }
9731            task.setResizeMode(resizeableMode);
9732        }
9733    }
9734
9735    @Override
9736    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9737        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9738        long ident = Binder.clearCallingIdentity();
9739        try {
9740            synchronized (this) {
9741                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9742                if (task == null) {
9743                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9744                    return;
9745                }
9746                // Place the task in the right stack if it isn't there already based on
9747                // the requested bounds.
9748                // The stack transition logic is:
9749                // - a null bounds on a freeform task moves that task to fullscreen
9750                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9751                //   that task to freeform
9752                // - otherwise the task is not moved
9753                int stackId = task.getStackId();
9754                if (!StackId.isTaskResizeAllowed(stackId)) {
9755                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9756                }
9757                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9758                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9759                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9760                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9761                }
9762                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9763                if (stackId != task.getStackId()) {
9764                    mStackSupervisor.moveTaskToStackUncheckedLocked(task, stackId, ON_TOP,
9765                            !FORCE_FOCUS, "resizeTask");
9766                    preserveWindow = false;
9767                }
9768
9769                task.resize(bounds, resizeMode, preserveWindow, false /* deferResume */);
9770            }
9771        } finally {
9772            Binder.restoreCallingIdentity(ident);
9773        }
9774    }
9775
9776    @Override
9777    public Rect getTaskBounds(int taskId) {
9778        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9779        long ident = Binder.clearCallingIdentity();
9780        Rect rect = new Rect();
9781        try {
9782            synchronized (this) {
9783                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9784                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9785                if (task == null) {
9786                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9787                    return rect;
9788                }
9789                if (task.getStack() != null) {
9790                    // Return the bounds from window manager since it will be adjusted for various
9791                    // things like the presense of a docked stack for tasks that aren't resizeable.
9792                    task.getWindowContainerBounds(rect);
9793                } else {
9794                    // Task isn't in window manager yet since it isn't associated with a stack.
9795                    // Return the persist value from activity manager
9796                    if (task.mBounds != null) {
9797                        rect.set(task.mBounds);
9798                    } else if (task.mLastNonFullscreenBounds != null) {
9799                        rect.set(task.mLastNonFullscreenBounds);
9800                    }
9801                }
9802            }
9803        } finally {
9804            Binder.restoreCallingIdentity(ident);
9805        }
9806        return rect;
9807    }
9808
9809    @Override
9810    public void cancelTaskWindowTransition(int taskId) {
9811        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskWindowTransition()");
9812        final long ident = Binder.clearCallingIdentity();
9813        try {
9814            synchronized (this) {
9815                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9816                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9817                if (task == null) {
9818                    Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
9819                    return;
9820                }
9821                task.cancelWindowTransition();
9822            }
9823        } finally {
9824            Binder.restoreCallingIdentity(ident);
9825        }
9826    }
9827
9828    @Override
9829    public void cancelTaskThumbnailTransition(int taskId) {
9830        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskThumbnailTransition()");
9831        final long ident = Binder.clearCallingIdentity();
9832        try {
9833            synchronized (this) {
9834                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9835                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9836                if (task == null) {
9837                    Slog.w(TAG, "cancelTaskThumbnailTransition: taskId=" + taskId + " not found");
9838                    return;
9839                }
9840                task.cancelThumbnailTransition();
9841            }
9842        } finally {
9843            Binder.restoreCallingIdentity(ident);
9844        }
9845    }
9846
9847    @Override
9848    public TaskSnapshot getTaskSnapshot(int taskId) {
9849        enforceCallingPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
9850        final long ident = Binder.clearCallingIdentity();
9851        try {
9852            final TaskRecord task;
9853            synchronized (this) {
9854                task = mStackSupervisor.anyTaskForIdLocked(
9855                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9856                if (task == null) {
9857                    Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
9858                    return null;
9859                }
9860            }
9861            // Don't call this while holding the lock as this operation might hit the disk.
9862            return task.getSnapshot();
9863        } finally {
9864            Binder.restoreCallingIdentity(ident);
9865        }
9866    }
9867
9868    @Override
9869    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9870        if (userId != UserHandle.getCallingUserId()) {
9871            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9872                    "getTaskDescriptionIcon");
9873        }
9874        final File passedIconFile = new File(filePath);
9875        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9876                passedIconFile.getName());
9877        if (!legitIconFile.getPath().equals(filePath)
9878                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9879            throw new IllegalArgumentException("Bad file path: " + filePath
9880                    + " passed for userId " + userId);
9881        }
9882        return mRecentTasks.getTaskDescriptionIcon(filePath);
9883    }
9884
9885    @Override
9886    public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
9887            throws RemoteException {
9888        final ActivityOptions activityOptions = ActivityOptions.fromBundle(opts);
9889        if (activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9890                activityOptions.getCustomInPlaceResId() == 0) {
9891            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9892                    "with valid animation");
9893        }
9894        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9895        mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
9896                activityOptions.getCustomInPlaceResId());
9897        mWindowManager.executeAppTransition();
9898    }
9899
9900    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9901        // Remove all tasks with activities in the specified package from the list of recent tasks
9902        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9903            TaskRecord tr = mRecentTasks.get(i);
9904            if (tr.userId != userId) continue;
9905
9906            ComponentName cn = tr.intent.getComponent();
9907            if (cn != null && cn.getPackageName().equals(packageName)) {
9908                // If the package name matches, remove the task.
9909                mStackSupervisor.removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9910            }
9911        }
9912    }
9913
9914    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9915            int userId) {
9916
9917        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9918            TaskRecord tr = mRecentTasks.get(i);
9919            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9920                continue;
9921            }
9922
9923            ComponentName cn = tr.intent.getComponent();
9924            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9925                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9926            if (sameComponent) {
9927                mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9928            }
9929        }
9930    }
9931
9932    @Override
9933    public void removeStack(int stackId) {
9934        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9935        if (StackId.isHomeOrRecentsStack(stackId)) {
9936            throw new IllegalArgumentException("Removing home or recents stack is not allowed.");
9937        }
9938
9939        synchronized (this) {
9940            final long ident = Binder.clearCallingIdentity();
9941            try {
9942                mStackSupervisor.removeStackLocked(stackId);
9943            } finally {
9944                Binder.restoreCallingIdentity(ident);
9945            }
9946        }
9947    }
9948
9949    @Override
9950    public void moveStackToDisplay(int stackId, int displayId) {
9951        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveStackToDisplay()");
9952
9953        synchronized (this) {
9954            final long ident = Binder.clearCallingIdentity();
9955            try {
9956                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
9957                        + " to displayId=" + displayId);
9958                mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
9959            } finally {
9960                Binder.restoreCallingIdentity(ident);
9961            }
9962        }
9963    }
9964
9965    @Override
9966    public boolean removeTask(int taskId) {
9967        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9968        synchronized (this) {
9969            final long ident = Binder.clearCallingIdentity();
9970            try {
9971                return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9972            } finally {
9973                Binder.restoreCallingIdentity(ident);
9974            }
9975        }
9976    }
9977
9978    /**
9979     * TODO: Add mController hook
9980     */
9981    @Override
9982    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9983        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9984
9985        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9986        synchronized(this) {
9987            moveTaskToFrontLocked(taskId, flags, bOptions);
9988        }
9989    }
9990
9991    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9992        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9993
9994        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9995                Binder.getCallingUid(), -1, -1, "Task to front")) {
9996            ActivityOptions.abort(options);
9997            return;
9998        }
9999        final long origId = Binder.clearCallingIdentity();
10000        try {
10001            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10002            if (task == null) {
10003                Slog.d(TAG, "Could not find task for id: "+ taskId);
10004                return;
10005            }
10006            if (mStackSupervisor.isLockTaskModeViolation(task)) {
10007                mStackSupervisor.showLockTaskToast();
10008                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
10009                return;
10010            }
10011            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
10012            if (prev != null) {
10013                task.setTaskToReturnTo(prev);
10014            }
10015            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
10016                    false /* forceNonResizable */);
10017
10018            final ActivityRecord topActivity = task.getTopActivity();
10019            if (topActivity != null) {
10020
10021                // We are reshowing a task, use a starting window to hide the initial draw delay
10022                // so the transition can start earlier.
10023                topActivity.showStartingWindow(null /* prev */, false /* newTask */,
10024                        true /* taskSwitch */);
10025            }
10026        } finally {
10027            Binder.restoreCallingIdentity(origId);
10028        }
10029        ActivityOptions.abort(options);
10030    }
10031
10032    /**
10033     * Moves an activity, and all of the other activities within the same task, to the bottom
10034     * of the history stack.  The activity's order within the task is unchanged.
10035     *
10036     * @param token A reference to the activity we wish to move
10037     * @param nonRoot If false then this only works if the activity is the root
10038     *                of a task; if true it will work for any activity in a task.
10039     * @return Returns true if the move completed, false if not.
10040     */
10041    @Override
10042    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
10043        enforceNotIsolatedCaller("moveActivityTaskToBack");
10044        synchronized(this) {
10045            final long origId = Binder.clearCallingIdentity();
10046            try {
10047                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
10048                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10049                if (task != null) {
10050                    if (mStackSupervisor.isLockedTask(task)) {
10051                        mStackSupervisor.showLockTaskToast();
10052                        return false;
10053                    }
10054                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
10055                }
10056            } finally {
10057                Binder.restoreCallingIdentity(origId);
10058            }
10059        }
10060        return false;
10061    }
10062
10063    @Override
10064    public void moveTaskBackwards(int task) {
10065        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
10066                "moveTaskBackwards()");
10067
10068        synchronized(this) {
10069            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10070                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
10071                return;
10072            }
10073            final long origId = Binder.clearCallingIdentity();
10074            moveTaskBackwardsLocked(task);
10075            Binder.restoreCallingIdentity(origId);
10076        }
10077    }
10078
10079    private final void moveTaskBackwardsLocked(int task) {
10080        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
10081    }
10082
10083    @Override
10084    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
10085            IActivityContainerCallback callback) throws RemoteException {
10086        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
10087        synchronized (this) {
10088            if (parentActivityToken == null) {
10089                throw new IllegalArgumentException("parent token must not be null");
10090            }
10091            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
10092            if (r == null) {
10093                return null;
10094            }
10095            if (callback == null) {
10096                throw new IllegalArgumentException("callback must not be null");
10097            }
10098            return mStackSupervisor.createVirtualActivityContainer(r, callback);
10099        }
10100    }
10101
10102    @Override
10103    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
10104        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
10105        synchronized (this) {
10106            final int stackId = mStackSupervisor.getNextStackId();
10107            final ActivityStack stack =
10108                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
10109            if (stack == null) {
10110                return null;
10111            }
10112            return stack.mActivityContainer;
10113        }
10114    }
10115
10116    @Override
10117    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
10118        synchronized (this) {
10119            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
10120            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
10121                return stack.mActivityContainer.getDisplayId();
10122            }
10123            return DEFAULT_DISPLAY;
10124        }
10125    }
10126
10127    @Override
10128    public int getActivityStackId(IBinder token) throws RemoteException {
10129        synchronized (this) {
10130            ActivityStack stack = ActivityRecord.getStackLocked(token);
10131            if (stack == null) {
10132                return INVALID_STACK_ID;
10133            }
10134            return stack.mStackId;
10135        }
10136    }
10137
10138    @Override
10139    public void exitFreeformMode(IBinder token) throws RemoteException {
10140        synchronized (this) {
10141            long ident = Binder.clearCallingIdentity();
10142            try {
10143                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10144                if (r == null) {
10145                    throw new IllegalArgumentException(
10146                            "exitFreeformMode: No activity record matching token=" + token);
10147                }
10148                final ActivityStack stack = r.getStackLocked(token);
10149                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
10150                    throw new IllegalStateException(
10151                            "exitFreeformMode: You can only go fullscreen from freeform.");
10152                }
10153                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
10154                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
10155                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
10156            } finally {
10157                Binder.restoreCallingIdentity(ident);
10158            }
10159        }
10160    }
10161
10162    @Override
10163    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
10164        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
10165        if (StackId.isHomeOrRecentsStack(stackId)) {
10166            throw new IllegalArgumentException(
10167                    "moveTaskToStack: Attempt to move task " + taskId + " to stack " + stackId);
10168        }
10169        synchronized (this) {
10170            long ident = Binder.clearCallingIdentity();
10171            try {
10172                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
10173                        + " to stackId=" + stackId + " toTop=" + toTop);
10174                if (stackId == DOCKED_STACK_ID) {
10175                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
10176                            null /* initialBounds */);
10177                }
10178                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
10179                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
10180                if (result && stackId == DOCKED_STACK_ID) {
10181                    // If task moved to docked stack - show recents if needed.
10182                    mWindowManager.showRecentApps(false /* fromHome */);
10183                }
10184            } finally {
10185                Binder.restoreCallingIdentity(ident);
10186            }
10187        }
10188    }
10189
10190    @Override
10191    public void swapDockedAndFullscreenStack() throws RemoteException {
10192        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
10193        synchronized (this) {
10194            long ident = Binder.clearCallingIdentity();
10195            try {
10196                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
10197                        FULLSCREEN_WORKSPACE_STACK_ID);
10198                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
10199                        : null;
10200                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
10201                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
10202                        : null;
10203                if (topTask == null || tasks == null || tasks.size() == 0) {
10204                    Slog.w(TAG,
10205                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
10206                    return;
10207                }
10208
10209                // TODO: App transition
10210                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
10211
10212                // Defer the resume so resume/pausing while moving stacks is dangerous.
10213                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
10214                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
10215                        ANIMATE, true /* deferResume */);
10216                final int size = tasks.size();
10217                for (int i = 0; i < size; i++) {
10218                    final int id = tasks.get(i).taskId;
10219                    if (id == topTask.taskId) {
10220                        continue;
10221                    }
10222                    mStackSupervisor.moveTaskToStackLocked(id,
10223                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
10224                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
10225                }
10226
10227                // Because we deferred the resume, to avoid conflicts with stack switches while
10228                // resuming, we need to do it after all the tasks are moved.
10229                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10230                mStackSupervisor.resumeFocusedStackTopActivityLocked();
10231
10232                mWindowManager.executeAppTransition();
10233            } finally {
10234                Binder.restoreCallingIdentity(ident);
10235            }
10236        }
10237    }
10238
10239    /**
10240     * Moves the input task to the docked stack.
10241     *
10242     * @param taskId Id of task to move.
10243     * @param createMode The mode the docked stack should be created in if it doesn't exist
10244     *                   already. See
10245     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
10246     *                   and
10247     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
10248     * @param toTop If the task and stack should be moved to the top.
10249     * @param animate Whether we should play an animation for the moving the task
10250     * @param initialBounds If the docked stack gets created, it will use these bounds for the
10251     *                      docked stack. Pass {@code null} to use default bounds.
10252     */
10253    @Override
10254    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
10255            Rect initialBounds, boolean moveHomeStackFront) {
10256        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
10257        synchronized (this) {
10258            long ident = Binder.clearCallingIdentity();
10259            try {
10260                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
10261                        + " to createMode=" + createMode + " toTop=" + toTop);
10262                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10263                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
10264                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
10265                        animate, DEFER_RESUME);
10266                if (moved) {
10267                    if (moveHomeStackFront) {
10268                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
10269                    }
10270                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10271                }
10272                return moved;
10273            } finally {
10274                Binder.restoreCallingIdentity(ident);
10275            }
10276        }
10277    }
10278
10279    /**
10280     * Moves the top activity in the input stackId to the pinned stack.
10281     *
10282     * @param stackId Id of stack to move the top activity to pinned stack.
10283     * @param bounds Bounds to use for pinned stack.
10284     *
10285     * @return True if the top activity of the input stack was successfully moved to the pinned
10286     *          stack.
10287     */
10288    @Override
10289    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10290        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10291        synchronized (this) {
10292            if (!mSupportsPictureInPicture) {
10293                throw new IllegalStateException("moveTopActivityToPinnedStack:"
10294                        + "Device doesn't support picture-in-pciture mode");
10295            }
10296
10297            long ident = Binder.clearCallingIdentity();
10298            try {
10299                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10300            } finally {
10301                Binder.restoreCallingIdentity(ident);
10302            }
10303        }
10304    }
10305
10306    @Override
10307    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
10308            boolean preserveWindows, boolean animate, int animationDuration) {
10309        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10310        long ident = Binder.clearCallingIdentity();
10311        try {
10312            synchronized (this) {
10313                if (animate) {
10314                    if (stackId == PINNED_STACK_ID) {
10315                        final ActivityStack pinnedStack =
10316                                mStackSupervisor.getStack(PINNED_STACK_ID);
10317                        pinnedStack.animateResizePinnedStack(bounds, animationDuration);
10318                    } else {
10319                        throw new IllegalArgumentException("Stack: " + stackId
10320                                + " doesn't support animated resize.");
10321                    }
10322                } else {
10323                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
10324                            null /* tempTaskInsetBounds */, preserveWindows,
10325                            allowResizeInDockedMode, !DEFER_RESUME);
10326                }
10327            }
10328        } finally {
10329            Binder.restoreCallingIdentity(ident);
10330        }
10331    }
10332
10333    @Override
10334    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10335            Rect tempDockedTaskInsetBounds,
10336            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10337        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10338                "resizeDockedStack()");
10339        long ident = Binder.clearCallingIdentity();
10340        try {
10341            synchronized (this) {
10342                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10343                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10344                        PRESERVE_WINDOWS);
10345            }
10346        } finally {
10347            Binder.restoreCallingIdentity(ident);
10348        }
10349    }
10350
10351    @Override
10352    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10353        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10354                "resizePinnedStack()");
10355        final long ident = Binder.clearCallingIdentity();
10356        try {
10357            synchronized (this) {
10358                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10359            }
10360        } finally {
10361            Binder.restoreCallingIdentity(ident);
10362        }
10363    }
10364
10365    /**
10366     * Try to place task to provided position. The final position might be different depending on
10367     * current user and stacks state. The task will be moved to target stack if it's currently in
10368     * different stack.
10369     */
10370    @Override
10371    public void positionTaskInStack(int taskId, int stackId, int position) {
10372        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10373        if (StackId.isHomeOrRecentsStack(stackId)) {
10374            throw new IllegalArgumentException(
10375                    "positionTaskInStack: Attempt to change the position of task "
10376                    + taskId + " in/to home/recents stack");
10377        }
10378        synchronized (this) {
10379            long ident = Binder.clearCallingIdentity();
10380            try {
10381                if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
10382                        + taskId + " in stackId=" + stackId + " at position=" + position);
10383                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10384                if (task == null) {
10385                    throw new IllegalArgumentException("positionTaskInStack: no task for id="
10386                            + taskId);
10387                }
10388
10389                final ActivityStack stack = mStackSupervisor.getStack(stackId, CREATE_IF_NEEDED,
10390                        !ON_TOP);
10391
10392                // TODO: Have the callers of this API call a separate reparent method if that is
10393                // what they intended to do vs. having this method also do reparenting.
10394                if (task.getStack() == stack) {
10395                    // Change position in current stack.
10396                    stack.positionChildAt(task, position);
10397                } else {
10398                    // Reparent to new stack.
10399                    task.reparent(stackId, position, "positionTaskInStack");
10400                }
10401            } finally {
10402                Binder.restoreCallingIdentity(ident);
10403            }
10404        }
10405    }
10406
10407    @Override
10408    public List<StackInfo> getAllStackInfos() {
10409        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10410        long ident = Binder.clearCallingIdentity();
10411        try {
10412            synchronized (this) {
10413                return mStackSupervisor.getAllStackInfosLocked();
10414            }
10415        } finally {
10416            Binder.restoreCallingIdentity(ident);
10417        }
10418    }
10419
10420    @Override
10421    public StackInfo getStackInfo(int stackId) {
10422        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10423        long ident = Binder.clearCallingIdentity();
10424        try {
10425            synchronized (this) {
10426                return mStackSupervisor.getStackInfoLocked(stackId);
10427            }
10428        } finally {
10429            Binder.restoreCallingIdentity(ident);
10430        }
10431    }
10432
10433    @Override
10434    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10435        synchronized(this) {
10436            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10437        }
10438    }
10439
10440    @Override
10441    public void updateDeviceOwner(String packageName) {
10442        final int callingUid = Binder.getCallingUid();
10443        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10444            throw new SecurityException("updateDeviceOwner called from non-system process");
10445        }
10446        synchronized (this) {
10447            mDeviceOwnerName = packageName;
10448        }
10449    }
10450
10451    @Override
10452    public void updateLockTaskPackages(int userId, String[] packages) {
10453        final int callingUid = Binder.getCallingUid();
10454        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10455            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10456                    "updateLockTaskPackages()");
10457        }
10458        synchronized (this) {
10459            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10460                    Arrays.toString(packages));
10461            mLockTaskPackages.put(userId, packages);
10462            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10463        }
10464    }
10465
10466
10467    void startLockTaskModeLocked(TaskRecord task) {
10468        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10469        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10470            return;
10471        }
10472
10473        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10474        // is initiated by system after the pinning request was shown and locked mode is initiated
10475        // by an authorized app directly
10476        final int callingUid = Binder.getCallingUid();
10477        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10478        long ident = Binder.clearCallingIdentity();
10479        try {
10480            if (!isSystemInitiated) {
10481                task.mLockTaskUid = callingUid;
10482                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10483                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10484                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10485                    StatusBarManagerInternal statusBarManager =
10486                            LocalServices.getService(StatusBarManagerInternal.class);
10487                    if (statusBarManager != null) {
10488                        statusBarManager.showScreenPinningRequest(task.taskId);
10489                    }
10490                    return;
10491                }
10492
10493                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10494                if (stack == null || task != stack.topTask()) {
10495                    throw new IllegalArgumentException("Invalid task, not in foreground");
10496                }
10497            }
10498            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10499                    "Locking fully");
10500            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10501                    ActivityManager.LOCK_TASK_MODE_PINNED :
10502                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10503                    "startLockTask", true);
10504        } finally {
10505            Binder.restoreCallingIdentity(ident);
10506        }
10507    }
10508
10509    @Override
10510    public void startLockTaskModeById(int taskId) {
10511        synchronized (this) {
10512            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10513            if (task != null) {
10514                startLockTaskModeLocked(task);
10515            }
10516        }
10517    }
10518
10519    @Override
10520    public void startLockTaskModeByToken(IBinder token) {
10521        synchronized (this) {
10522            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10523            if (r == null) {
10524                return;
10525            }
10526            final TaskRecord task = r.task;
10527            if (task != null) {
10528                startLockTaskModeLocked(task);
10529            }
10530        }
10531    }
10532
10533    @Override
10534    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10535        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10536        // This makes inner call to look as if it was initiated by system.
10537        long ident = Binder.clearCallingIdentity();
10538        try {
10539            synchronized (this) {
10540                startLockTaskModeById(taskId);
10541            }
10542        } finally {
10543            Binder.restoreCallingIdentity(ident);
10544        }
10545    }
10546
10547    @Override
10548    public void stopLockTaskMode() {
10549        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10550        if (lockTask == null) {
10551            // Our work here is done.
10552            return;
10553        }
10554
10555        final int callingUid = Binder.getCallingUid();
10556        final int lockTaskUid = lockTask.mLockTaskUid;
10557        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10558        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10559            // Done.
10560            return;
10561        } else {
10562            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10563            // It is possible lockTaskMode was started by the system process because
10564            // android:lockTaskMode is set to a locking value in the application manifest
10565            // instead of the app calling startLockTaskMode. In this case
10566            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10567            // {@link TaskRecord.effectiveUid} instead. Also caller with
10568            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10569            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10570                    && callingUid != lockTaskUid
10571                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10572                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10573                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10574            }
10575        }
10576        long ident = Binder.clearCallingIdentity();
10577        try {
10578            Log.d(TAG, "stopLockTaskMode");
10579            // Stop lock task
10580            synchronized (this) {
10581                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10582                        "stopLockTask", true);
10583            }
10584            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10585            if (tm != null) {
10586                tm.showInCallScreen(false);
10587            }
10588        } finally {
10589            Binder.restoreCallingIdentity(ident);
10590        }
10591    }
10592
10593    /**
10594     * This API should be called by SystemUI only when user perform certain action to dismiss
10595     * lock task mode. We should only dismiss pinned lock task mode in this case.
10596     */
10597    @Override
10598    public void stopSystemLockTaskMode() throws RemoteException {
10599        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10600            stopLockTaskMode();
10601        } else {
10602            mStackSupervisor.showLockTaskToast();
10603        }
10604    }
10605
10606    @Override
10607    public boolean isInLockTaskMode() {
10608        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10609    }
10610
10611    @Override
10612    public int getLockTaskModeState() {
10613        synchronized (this) {
10614            return mStackSupervisor.getLockTaskModeState();
10615        }
10616    }
10617
10618    @Override
10619    public void showLockTaskEscapeMessage(IBinder token) {
10620        synchronized (this) {
10621            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10622            if (r == null) {
10623                return;
10624            }
10625            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10626        }
10627    }
10628
10629    // =========================================================
10630    // CONTENT PROVIDERS
10631    // =========================================================
10632
10633    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10634        List<ProviderInfo> providers = null;
10635        try {
10636            providers = AppGlobals.getPackageManager()
10637                    .queryContentProviders(app.processName, app.uid,
10638                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10639                                    | MATCH_DEBUG_TRIAGED_MISSING)
10640                    .getList();
10641        } catch (RemoteException ex) {
10642        }
10643        if (DEBUG_MU) Slog.v(TAG_MU,
10644                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10645        int userId = app.userId;
10646        if (providers != null) {
10647            int N = providers.size();
10648            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10649            for (int i=0; i<N; i++) {
10650                // TODO: keep logic in sync with installEncryptionUnawareProviders
10651                ProviderInfo cpi =
10652                    (ProviderInfo)providers.get(i);
10653                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10654                        cpi.name, cpi.flags);
10655                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10656                    // This is a singleton provider, but a user besides the
10657                    // default user is asking to initialize a process it runs
10658                    // in...  well, no, it doesn't actually run in this process,
10659                    // it runs in the process of the default user.  Get rid of it.
10660                    providers.remove(i);
10661                    N--;
10662                    i--;
10663                    continue;
10664                }
10665
10666                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10667                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10668                if (cpr == null) {
10669                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10670                    mProviderMap.putProviderByClass(comp, cpr);
10671                }
10672                if (DEBUG_MU) Slog.v(TAG_MU,
10673                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10674                app.pubProviders.put(cpi.name, cpr);
10675                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10676                    // Don't add this if it is a platform component that is marked
10677                    // to run in multiple processes, because this is actually
10678                    // part of the framework so doesn't make sense to track as a
10679                    // separate apk in the process.
10680                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10681                            mProcessStats);
10682                }
10683                notifyPackageUse(cpi.applicationInfo.packageName,
10684                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10685            }
10686        }
10687        return providers;
10688    }
10689
10690    /**
10691     * Check if the calling UID has a possible chance at accessing the provider
10692     * at the given authority and user.
10693     */
10694    public String checkContentProviderAccess(String authority, int userId) {
10695        if (userId == UserHandle.USER_ALL) {
10696            mContext.enforceCallingOrSelfPermission(
10697                    Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
10698            userId = UserHandle.getCallingUserId();
10699        }
10700
10701        ProviderInfo cpi = null;
10702        try {
10703            cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
10704                    STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10705                            | PackageManager.MATCH_DIRECT_BOOT_AWARE
10706                            | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
10707                    userId);
10708        } catch (RemoteException ignored) {
10709        }
10710        if (cpi == null) {
10711            // TODO: make this an outright failure in a future platform release;
10712            // until then anonymous content notifications are unprotected
10713            //return "Failed to find provider " + authority + " for user " + userId;
10714            return null;
10715        }
10716
10717        ProcessRecord r = null;
10718        synchronized (mPidsSelfLocked) {
10719            r = mPidsSelfLocked.get(Binder.getCallingPid());
10720        }
10721        if (r == null) {
10722            return "Failed to find PID " + Binder.getCallingPid();
10723        }
10724
10725        synchronized (this) {
10726            return checkContentProviderPermissionLocked(cpi, r, userId, true);
10727        }
10728    }
10729
10730    /**
10731     * Check if {@link ProcessRecord} has a possible chance at accessing the
10732     * given {@link ProviderInfo}. Final permission checking is always done
10733     * in {@link ContentProvider}.
10734     */
10735    private final String checkContentProviderPermissionLocked(
10736            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10737        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10738        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10739        boolean checkedGrants = false;
10740        if (checkUser) {
10741            // Looking for cross-user grants before enforcing the typical cross-users permissions
10742            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10743            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10744                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10745                    return null;
10746                }
10747                checkedGrants = true;
10748            }
10749            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10750                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10751            if (userId != tmpTargetUserId) {
10752                // When we actually went to determine the final targer user ID, this ended
10753                // up different than our initial check for the authority.  This is because
10754                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10755                // SELF.  So we need to re-check the grants again.
10756                checkedGrants = false;
10757            }
10758        }
10759        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10760                cpi.applicationInfo.uid, cpi.exported)
10761                == PackageManager.PERMISSION_GRANTED) {
10762            return null;
10763        }
10764        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10765                cpi.applicationInfo.uid, cpi.exported)
10766                == PackageManager.PERMISSION_GRANTED) {
10767            return null;
10768        }
10769
10770        PathPermission[] pps = cpi.pathPermissions;
10771        if (pps != null) {
10772            int i = pps.length;
10773            while (i > 0) {
10774                i--;
10775                PathPermission pp = pps[i];
10776                String pprperm = pp.getReadPermission();
10777                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10778                        cpi.applicationInfo.uid, cpi.exported)
10779                        == PackageManager.PERMISSION_GRANTED) {
10780                    return null;
10781                }
10782                String ppwperm = pp.getWritePermission();
10783                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10784                        cpi.applicationInfo.uid, cpi.exported)
10785                        == PackageManager.PERMISSION_GRANTED) {
10786                    return null;
10787                }
10788            }
10789        }
10790        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10791            return null;
10792        }
10793
10794        String msg;
10795        if (!cpi.exported) {
10796            msg = "Permission Denial: opening provider " + cpi.name
10797                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10798                    + ", uid=" + callingUid + ") that is not exported from uid "
10799                    + cpi.applicationInfo.uid;
10800        } else {
10801            msg = "Permission Denial: opening provider " + cpi.name
10802                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10803                    + ", uid=" + callingUid + ") requires "
10804                    + cpi.readPermission + " or " + cpi.writePermission;
10805        }
10806        Slog.w(TAG, msg);
10807        return msg;
10808    }
10809
10810    /**
10811     * Returns if the ContentProvider has granted a uri to callingUid
10812     */
10813    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10814        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10815        if (perms != null) {
10816            for (int i=perms.size()-1; i>=0; i--) {
10817                GrantUri grantUri = perms.keyAt(i);
10818                if (grantUri.sourceUserId == userId || !checkUser) {
10819                    if (matchesProvider(grantUri.uri, cpi)) {
10820                        return true;
10821                    }
10822                }
10823            }
10824        }
10825        return false;
10826    }
10827
10828    /**
10829     * Returns true if the uri authority is one of the authorities specified in the provider.
10830     */
10831    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10832        String uriAuth = uri.getAuthority();
10833        String cpiAuth = cpi.authority;
10834        if (cpiAuth.indexOf(';') == -1) {
10835            return cpiAuth.equals(uriAuth);
10836        }
10837        String[] cpiAuths = cpiAuth.split(";");
10838        int length = cpiAuths.length;
10839        for (int i = 0; i < length; i++) {
10840            if (cpiAuths[i].equals(uriAuth)) return true;
10841        }
10842        return false;
10843    }
10844
10845    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10846            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10847        if (r != null) {
10848            for (int i=0; i<r.conProviders.size(); i++) {
10849                ContentProviderConnection conn = r.conProviders.get(i);
10850                if (conn.provider == cpr) {
10851                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10852                            "Adding provider requested by "
10853                            + r.processName + " from process "
10854                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10855                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10856                    if (stable) {
10857                        conn.stableCount++;
10858                        conn.numStableIncs++;
10859                    } else {
10860                        conn.unstableCount++;
10861                        conn.numUnstableIncs++;
10862                    }
10863                    return conn;
10864                }
10865            }
10866            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10867            if (stable) {
10868                conn.stableCount = 1;
10869                conn.numStableIncs = 1;
10870            } else {
10871                conn.unstableCount = 1;
10872                conn.numUnstableIncs = 1;
10873            }
10874            cpr.connections.add(conn);
10875            r.conProviders.add(conn);
10876            startAssociationLocked(r.uid, r.processName, r.curProcState,
10877                    cpr.uid, cpr.name, cpr.info.processName);
10878            return conn;
10879        }
10880        cpr.addExternalProcessHandleLocked(externalProcessToken);
10881        return null;
10882    }
10883
10884    boolean decProviderCountLocked(ContentProviderConnection conn,
10885            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10886        if (conn != null) {
10887            cpr = conn.provider;
10888            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10889                    "Removing provider requested by "
10890                    + conn.client.processName + " from process "
10891                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10892                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10893            if (stable) {
10894                conn.stableCount--;
10895            } else {
10896                conn.unstableCount--;
10897            }
10898            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10899                cpr.connections.remove(conn);
10900                conn.client.conProviders.remove(conn);
10901                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10902                    // The client is more important than last activity -- note the time this
10903                    // is happening, so we keep the old provider process around a bit as last
10904                    // activity to avoid thrashing it.
10905                    if (cpr.proc != null) {
10906                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10907                    }
10908                }
10909                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10910                return true;
10911            }
10912            return false;
10913        }
10914        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10915        return false;
10916    }
10917
10918    private void checkTime(long startTime, String where) {
10919        long now = SystemClock.uptimeMillis();
10920        if ((now-startTime) > 50) {
10921            // If we are taking more than 50ms, log about it.
10922            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10923        }
10924    }
10925
10926    private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
10927            PROC_SPACE_TERM,
10928            PROC_SPACE_TERM|PROC_PARENS,
10929            PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
10930    };
10931
10932    private final long[] mProcessStateStatsLongs = new long[1];
10933
10934    boolean isProcessAliveLocked(ProcessRecord proc) {
10935        if (proc.procStatFile == null) {
10936            proc.procStatFile = "/proc/" + proc.pid + "/stat";
10937        }
10938        mProcessStateStatsLongs[0] = 0;
10939        if (!Process.readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
10940                mProcessStateStatsLongs, null)) {
10941            if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
10942            return false;
10943        }
10944        final long state = mProcessStateStatsLongs[0];
10945        if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
10946                + (char)state);
10947        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
10948    }
10949
10950    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10951            String name, IBinder token, boolean stable, int userId) {
10952        ContentProviderRecord cpr;
10953        ContentProviderConnection conn = null;
10954        ProviderInfo cpi = null;
10955
10956        synchronized(this) {
10957            long startTime = SystemClock.uptimeMillis();
10958
10959            ProcessRecord r = null;
10960            if (caller != null) {
10961                r = getRecordForAppLocked(caller);
10962                if (r == null) {
10963                    throw new SecurityException(
10964                            "Unable to find app for caller " + caller
10965                          + " (pid=" + Binder.getCallingPid()
10966                          + ") when getting content provider " + name);
10967                }
10968            }
10969
10970            boolean checkCrossUser = true;
10971
10972            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10973
10974            // First check if this content provider has been published...
10975            cpr = mProviderMap.getProviderByName(name, userId);
10976            // If that didn't work, check if it exists for user 0 and then
10977            // verify that it's a singleton provider before using it.
10978            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10979                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10980                if (cpr != null) {
10981                    cpi = cpr.info;
10982                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10983                            cpi.name, cpi.flags)
10984                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10985                        userId = UserHandle.USER_SYSTEM;
10986                        checkCrossUser = false;
10987                    } else {
10988                        cpr = null;
10989                        cpi = null;
10990                    }
10991                }
10992            }
10993
10994            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
10995            if (providerRunning) {
10996                cpi = cpr.info;
10997                String msg;
10998                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10999                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
11000                        != null) {
11001                    throw new SecurityException(msg);
11002                }
11003                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11004
11005                if (r != null && cpr.canRunHere(r)) {
11006                    // This provider has been published or is in the process
11007                    // of being published...  but it is also allowed to run
11008                    // in the caller's process, so don't make a connection
11009                    // and just let the caller instantiate its own instance.
11010                    ContentProviderHolder holder = cpr.newHolder(null);
11011                    // don't give caller the provider object, it needs
11012                    // to make its own.
11013                    holder.provider = null;
11014                    return holder;
11015                }
11016
11017                final long origId = Binder.clearCallingIdentity();
11018
11019                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
11020
11021                // In this case the provider instance already exists, so we can
11022                // return it right away.
11023                conn = incProviderCountLocked(r, cpr, token, stable);
11024                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
11025                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
11026                        // If this is a perceptible app accessing the provider,
11027                        // make sure to count it as being accessed and thus
11028                        // back up on the LRU list.  This is good because
11029                        // content providers are often expensive to start.
11030                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
11031                        updateLruProcessLocked(cpr.proc, false, null);
11032                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
11033                    }
11034                }
11035
11036                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
11037                final int verifiedAdj = cpr.proc.verifiedAdj;
11038                boolean success = updateOomAdjLocked(cpr.proc);
11039                // XXX things have changed so updateOomAdjLocked doesn't actually tell us
11040                // if the process has been successfully adjusted.  So to reduce races with
11041                // it, we will check whether the process still exists.  Note that this doesn't
11042                // completely get rid of races with LMK killing the process, but should make
11043                // them much smaller.
11044                if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
11045                    success = false;
11046                }
11047                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
11048                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
11049                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
11050                // NOTE: there is still a race here where a signal could be
11051                // pending on the process even though we managed to update its
11052                // adj level.  Not sure what to do about this, but at least
11053                // the race is now smaller.
11054                if (!success) {
11055                    // Uh oh...  it looks like the provider's process
11056                    // has been killed on us.  We need to wait for a new
11057                    // process to be started, and make sure its death
11058                    // doesn't kill our process.
11059                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
11060                            + " is crashing; detaching " + r);
11061                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
11062                    checkTime(startTime, "getContentProviderImpl: before appDied");
11063                    appDiedLocked(cpr.proc);
11064                    checkTime(startTime, "getContentProviderImpl: after appDied");
11065                    if (!lastRef) {
11066                        // This wasn't the last ref our process had on
11067                        // the provider...  we have now been killed, bail.
11068                        return null;
11069                    }
11070                    providerRunning = false;
11071                    conn = null;
11072                } else {
11073                    cpr.proc.verifiedAdj = cpr.proc.setAdj;
11074                }
11075
11076                Binder.restoreCallingIdentity(origId);
11077            }
11078
11079            if (!providerRunning) {
11080                try {
11081                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
11082                    cpi = AppGlobals.getPackageManager().
11083                        resolveContentProvider(name,
11084                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
11085                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
11086                } catch (RemoteException ex) {
11087                }
11088                if (cpi == null) {
11089                    return null;
11090                }
11091                // If the provider is a singleton AND
11092                // (it's a call within the same user || the provider is a
11093                // privileged app)
11094                // Then allow connecting to the singleton provider
11095                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11096                        cpi.name, cpi.flags)
11097                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
11098                if (singleton) {
11099                    userId = UserHandle.USER_SYSTEM;
11100                }
11101                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
11102                checkTime(startTime, "getContentProviderImpl: got app info for user");
11103
11104                String msg;
11105                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11106                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
11107                        != null) {
11108                    throw new SecurityException(msg);
11109                }
11110                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11111
11112                if (!mProcessesReady
11113                        && !cpi.processName.equals("system")) {
11114                    // If this content provider does not run in the system
11115                    // process, and the system is not yet ready to run other
11116                    // processes, then fail fast instead of hanging.
11117                    throw new IllegalArgumentException(
11118                            "Attempt to launch content provider before system ready");
11119                }
11120
11121                // Make sure that the user who owns this provider is running.  If not,
11122                // we don't want to allow it to run.
11123                if (!mUserController.isUserRunningLocked(userId, 0)) {
11124                    Slog.w(TAG, "Unable to launch app "
11125                            + cpi.applicationInfo.packageName + "/"
11126                            + cpi.applicationInfo.uid + " for provider "
11127                            + name + ": user " + userId + " is stopped");
11128                    return null;
11129                }
11130
11131                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11132                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
11133                cpr = mProviderMap.getProviderByClass(comp, userId);
11134                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
11135                final boolean firstClass = cpr == null;
11136                if (firstClass) {
11137                    final long ident = Binder.clearCallingIdentity();
11138
11139                    // If permissions need a review before any of the app components can run,
11140                    // we return no provider and launch a review activity if the calling app
11141                    // is in the foreground.
11142                    if (mPermissionReviewRequired) {
11143                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
11144                            return null;
11145                        }
11146                    }
11147
11148                    try {
11149                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
11150                        ApplicationInfo ai =
11151                            AppGlobals.getPackageManager().
11152                                getApplicationInfo(
11153                                        cpi.applicationInfo.packageName,
11154                                        STOCK_PM_FLAGS, userId);
11155                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
11156                        if (ai == null) {
11157                            Slog.w(TAG, "No package info for content provider "
11158                                    + cpi.name);
11159                            return null;
11160                        }
11161                        ai = getAppInfoForUser(ai, userId);
11162                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
11163                    } catch (RemoteException ex) {
11164                        // pm is in same process, this will never happen.
11165                    } finally {
11166                        Binder.restoreCallingIdentity(ident);
11167                    }
11168                }
11169
11170                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
11171
11172                if (r != null && cpr.canRunHere(r)) {
11173                    // If this is a multiprocess provider, then just return its
11174                    // info and allow the caller to instantiate it.  Only do
11175                    // this if the provider is the same user as the caller's
11176                    // process, or can run as root (so can be in any process).
11177                    return cpr.newHolder(null);
11178                }
11179
11180                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
11181                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
11182                            + cpr.info.name + " callers=" + Debug.getCallers(6));
11183
11184                // This is single process, and our app is now connecting to it.
11185                // See if we are already in the process of launching this
11186                // provider.
11187                final int N = mLaunchingProviders.size();
11188                int i;
11189                for (i = 0; i < N; i++) {
11190                    if (mLaunchingProviders.get(i) == cpr) {
11191                        break;
11192                    }
11193                }
11194
11195                // If the provider is not already being launched, then get it
11196                // started.
11197                if (i >= N) {
11198                    final long origId = Binder.clearCallingIdentity();
11199
11200                    try {
11201                        // Content provider is now in use, its package can't be stopped.
11202                        try {
11203                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
11204                            AppGlobals.getPackageManager().setPackageStoppedState(
11205                                    cpr.appInfo.packageName, false, userId);
11206                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
11207                        } catch (RemoteException e) {
11208                        } catch (IllegalArgumentException e) {
11209                            Slog.w(TAG, "Failed trying to unstop package "
11210                                    + cpr.appInfo.packageName + ": " + e);
11211                        }
11212
11213                        // Use existing process if already started
11214                        checkTime(startTime, "getContentProviderImpl: looking for process record");
11215                        ProcessRecord proc = getProcessRecordLocked(
11216                                cpi.processName, cpr.appInfo.uid, false);
11217                        if (proc != null && proc.thread != null && !proc.killed) {
11218                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
11219                                    "Installing in existing process " + proc);
11220                            if (!proc.pubProviders.containsKey(cpi.name)) {
11221                                checkTime(startTime, "getContentProviderImpl: scheduling install");
11222                                proc.pubProviders.put(cpi.name, cpr);
11223                                try {
11224                                    proc.thread.scheduleInstallProvider(cpi);
11225                                } catch (RemoteException e) {
11226                                }
11227                            }
11228                        } else {
11229                            checkTime(startTime, "getContentProviderImpl: before start process");
11230                            proc = startProcessLocked(cpi.processName,
11231                                    cpr.appInfo, false, 0, "content provider",
11232                                    new ComponentName(cpi.applicationInfo.packageName,
11233                                            cpi.name), false, false, false);
11234                            checkTime(startTime, "getContentProviderImpl: after start process");
11235                            if (proc == null) {
11236                                Slog.w(TAG, "Unable to launch app "
11237                                        + cpi.applicationInfo.packageName + "/"
11238                                        + cpi.applicationInfo.uid + " for provider "
11239                                        + name + ": process is bad");
11240                                return null;
11241                            }
11242                        }
11243                        cpr.launchingApp = proc;
11244                        mLaunchingProviders.add(cpr);
11245                    } finally {
11246                        Binder.restoreCallingIdentity(origId);
11247                    }
11248                }
11249
11250                checkTime(startTime, "getContentProviderImpl: updating data structures");
11251
11252                // Make sure the provider is published (the same provider class
11253                // may be published under multiple names).
11254                if (firstClass) {
11255                    mProviderMap.putProviderByClass(comp, cpr);
11256                }
11257
11258                mProviderMap.putProviderByName(name, cpr);
11259                conn = incProviderCountLocked(r, cpr, token, stable);
11260                if (conn != null) {
11261                    conn.waiting = true;
11262                }
11263            }
11264            checkTime(startTime, "getContentProviderImpl: done!");
11265        }
11266
11267        // Wait for the provider to be published...
11268        synchronized (cpr) {
11269            while (cpr.provider == null) {
11270                if (cpr.launchingApp == null) {
11271                    Slog.w(TAG, "Unable to launch app "
11272                            + cpi.applicationInfo.packageName + "/"
11273                            + cpi.applicationInfo.uid + " for provider "
11274                            + name + ": launching app became null");
11275                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
11276                            UserHandle.getUserId(cpi.applicationInfo.uid),
11277                            cpi.applicationInfo.packageName,
11278                            cpi.applicationInfo.uid, name);
11279                    return null;
11280                }
11281                try {
11282                    if (DEBUG_MU) Slog.v(TAG_MU,
11283                            "Waiting to start provider " + cpr
11284                            + " launchingApp=" + cpr.launchingApp);
11285                    if (conn != null) {
11286                        conn.waiting = true;
11287                    }
11288                    cpr.wait();
11289                } catch (InterruptedException ex) {
11290                } finally {
11291                    if (conn != null) {
11292                        conn.waiting = false;
11293                    }
11294                }
11295            }
11296        }
11297        return cpr != null ? cpr.newHolder(conn) : null;
11298    }
11299
11300    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11301            ProcessRecord r, final int userId) {
11302        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11303                cpi.packageName, userId)) {
11304
11305            final boolean callerForeground = r == null || r.setSchedGroup
11306                    != ProcessList.SCHED_GROUP_BACKGROUND;
11307
11308            // Show a permission review UI only for starting from a foreground app
11309            if (!callerForeground) {
11310                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11311                        + cpi.packageName + " requires a permissions review");
11312                return false;
11313            }
11314
11315            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11316            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11317                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11318            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11319
11320            if (DEBUG_PERMISSIONS_REVIEW) {
11321                Slog.i(TAG, "u" + userId + " Launching permission review "
11322                        + "for package " + cpi.packageName);
11323            }
11324
11325            final UserHandle userHandle = new UserHandle(userId);
11326            mHandler.post(new Runnable() {
11327                @Override
11328                public void run() {
11329                    mContext.startActivityAsUser(intent, userHandle);
11330                }
11331            });
11332
11333            return false;
11334        }
11335
11336        return true;
11337    }
11338
11339    PackageManagerInternal getPackageManagerInternalLocked() {
11340        if (mPackageManagerInt == null) {
11341            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11342        }
11343        return mPackageManagerInt;
11344    }
11345
11346    @Override
11347    public final ContentProviderHolder getContentProvider(
11348            IApplicationThread caller, String name, int userId, boolean stable) {
11349        enforceNotIsolatedCaller("getContentProvider");
11350        if (caller == null) {
11351            String msg = "null IApplicationThread when getting content provider "
11352                    + name;
11353            Slog.w(TAG, msg);
11354            throw new SecurityException(msg);
11355        }
11356        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11357        // with cross-user grant.
11358        return getContentProviderImpl(caller, name, null, stable, userId);
11359    }
11360
11361    public ContentProviderHolder getContentProviderExternal(
11362            String name, int userId, IBinder token) {
11363        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11364            "Do not have permission in call getContentProviderExternal()");
11365        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11366                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11367        return getContentProviderExternalUnchecked(name, token, userId);
11368    }
11369
11370    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11371            IBinder token, int userId) {
11372        return getContentProviderImpl(null, name, token, true, userId);
11373    }
11374
11375    /**
11376     * Drop a content provider from a ProcessRecord's bookkeeping
11377     */
11378    public void removeContentProvider(IBinder connection, boolean stable) {
11379        enforceNotIsolatedCaller("removeContentProvider");
11380        long ident = Binder.clearCallingIdentity();
11381        try {
11382            synchronized (this) {
11383                ContentProviderConnection conn;
11384                try {
11385                    conn = (ContentProviderConnection)connection;
11386                } catch (ClassCastException e) {
11387                    String msg ="removeContentProvider: " + connection
11388                            + " not a ContentProviderConnection";
11389                    Slog.w(TAG, msg);
11390                    throw new IllegalArgumentException(msg);
11391                }
11392                if (conn == null) {
11393                    throw new NullPointerException("connection is null");
11394                }
11395                if (decProviderCountLocked(conn, null, null, stable)) {
11396                    updateOomAdjLocked();
11397                }
11398            }
11399        } finally {
11400            Binder.restoreCallingIdentity(ident);
11401        }
11402    }
11403
11404    public void removeContentProviderExternal(String name, IBinder token) {
11405        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11406            "Do not have permission in call removeContentProviderExternal()");
11407        int userId = UserHandle.getCallingUserId();
11408        long ident = Binder.clearCallingIdentity();
11409        try {
11410            removeContentProviderExternalUnchecked(name, token, userId);
11411        } finally {
11412            Binder.restoreCallingIdentity(ident);
11413        }
11414    }
11415
11416    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11417        synchronized (this) {
11418            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11419            if(cpr == null) {
11420                //remove from mProvidersByClass
11421                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11422                return;
11423            }
11424
11425            //update content provider record entry info
11426            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11427            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11428            if (localCpr.hasExternalProcessHandles()) {
11429                if (localCpr.removeExternalProcessHandleLocked(token)) {
11430                    updateOomAdjLocked();
11431                } else {
11432                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11433                            + " with no external reference for token: "
11434                            + token + ".");
11435                }
11436            } else {
11437                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11438                        + " with no external references.");
11439            }
11440        }
11441    }
11442
11443    public final void publishContentProviders(IApplicationThread caller,
11444            List<ContentProviderHolder> providers) {
11445        if (providers == null) {
11446            return;
11447        }
11448
11449        enforceNotIsolatedCaller("publishContentProviders");
11450        synchronized (this) {
11451            final ProcessRecord r = getRecordForAppLocked(caller);
11452            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11453            if (r == null) {
11454                throw new SecurityException(
11455                        "Unable to find app for caller " + caller
11456                      + " (pid=" + Binder.getCallingPid()
11457                      + ") when publishing content providers");
11458            }
11459
11460            final long origId = Binder.clearCallingIdentity();
11461
11462            final int N = providers.size();
11463            for (int i = 0; i < N; i++) {
11464                ContentProviderHolder src = providers.get(i);
11465                if (src == null || src.info == null || src.provider == null) {
11466                    continue;
11467                }
11468                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11469                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11470                if (dst != null) {
11471                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11472                    mProviderMap.putProviderByClass(comp, dst);
11473                    String names[] = dst.info.authority.split(";");
11474                    for (int j = 0; j < names.length; j++) {
11475                        mProviderMap.putProviderByName(names[j], dst);
11476                    }
11477
11478                    int launchingCount = mLaunchingProviders.size();
11479                    int j;
11480                    boolean wasInLaunchingProviders = false;
11481                    for (j = 0; j < launchingCount; j++) {
11482                        if (mLaunchingProviders.get(j) == dst) {
11483                            mLaunchingProviders.remove(j);
11484                            wasInLaunchingProviders = true;
11485                            j--;
11486                            launchingCount--;
11487                        }
11488                    }
11489                    if (wasInLaunchingProviders) {
11490                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11491                    }
11492                    synchronized (dst) {
11493                        dst.provider = src.provider;
11494                        dst.proc = r;
11495                        dst.notifyAll();
11496                    }
11497                    updateOomAdjLocked(r);
11498                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11499                            src.info.authority);
11500                }
11501            }
11502
11503            Binder.restoreCallingIdentity(origId);
11504        }
11505    }
11506
11507    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11508        ContentProviderConnection conn;
11509        try {
11510            conn = (ContentProviderConnection)connection;
11511        } catch (ClassCastException e) {
11512            String msg ="refContentProvider: " + connection
11513                    + " not a ContentProviderConnection";
11514            Slog.w(TAG, msg);
11515            throw new IllegalArgumentException(msg);
11516        }
11517        if (conn == null) {
11518            throw new NullPointerException("connection is null");
11519        }
11520
11521        synchronized (this) {
11522            if (stable > 0) {
11523                conn.numStableIncs += stable;
11524            }
11525            stable = conn.stableCount + stable;
11526            if (stable < 0) {
11527                throw new IllegalStateException("stableCount < 0: " + stable);
11528            }
11529
11530            if (unstable > 0) {
11531                conn.numUnstableIncs += unstable;
11532            }
11533            unstable = conn.unstableCount + unstable;
11534            if (unstable < 0) {
11535                throw new IllegalStateException("unstableCount < 0: " + unstable);
11536            }
11537
11538            if ((stable+unstable) <= 0) {
11539                throw new IllegalStateException("ref counts can't go to zero here: stable="
11540                        + stable + " unstable=" + unstable);
11541            }
11542            conn.stableCount = stable;
11543            conn.unstableCount = unstable;
11544            return !conn.dead;
11545        }
11546    }
11547
11548    public void unstableProviderDied(IBinder connection) {
11549        ContentProviderConnection conn;
11550        try {
11551            conn = (ContentProviderConnection)connection;
11552        } catch (ClassCastException e) {
11553            String msg ="refContentProvider: " + connection
11554                    + " not a ContentProviderConnection";
11555            Slog.w(TAG, msg);
11556            throw new IllegalArgumentException(msg);
11557        }
11558        if (conn == null) {
11559            throw new NullPointerException("connection is null");
11560        }
11561
11562        // Safely retrieve the content provider associated with the connection.
11563        IContentProvider provider;
11564        synchronized (this) {
11565            provider = conn.provider.provider;
11566        }
11567
11568        if (provider == null) {
11569            // Um, yeah, we're way ahead of you.
11570            return;
11571        }
11572
11573        // Make sure the caller is being honest with us.
11574        if (provider.asBinder().pingBinder()) {
11575            // Er, no, still looks good to us.
11576            synchronized (this) {
11577                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11578                        + " says " + conn + " died, but we don't agree");
11579                return;
11580            }
11581        }
11582
11583        // Well look at that!  It's dead!
11584        synchronized (this) {
11585            if (conn.provider.provider != provider) {
11586                // But something changed...  good enough.
11587                return;
11588            }
11589
11590            ProcessRecord proc = conn.provider.proc;
11591            if (proc == null || proc.thread == null) {
11592                // Seems like the process is already cleaned up.
11593                return;
11594            }
11595
11596            // As far as we're concerned, this is just like receiving a
11597            // death notification...  just a bit prematurely.
11598            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11599                    + ") early provider death");
11600            final long ident = Binder.clearCallingIdentity();
11601            try {
11602                appDiedLocked(proc);
11603            } finally {
11604                Binder.restoreCallingIdentity(ident);
11605            }
11606        }
11607    }
11608
11609    @Override
11610    public void appNotRespondingViaProvider(IBinder connection) {
11611        enforceCallingPermission(
11612                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11613
11614        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11615        if (conn == null) {
11616            Slog.w(TAG, "ContentProviderConnection is null");
11617            return;
11618        }
11619
11620        final ProcessRecord host = conn.provider.proc;
11621        if (host == null) {
11622            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11623            return;
11624        }
11625
11626        mHandler.post(new Runnable() {
11627            @Override
11628            public void run() {
11629                mAppErrors.appNotResponding(host, null, null, false,
11630                        "ContentProvider not responding");
11631            }
11632        });
11633    }
11634
11635    public final void installSystemProviders() {
11636        List<ProviderInfo> providers;
11637        synchronized (this) {
11638            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11639            providers = generateApplicationProvidersLocked(app);
11640            if (providers != null) {
11641                for (int i=providers.size()-1; i>=0; i--) {
11642                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11643                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11644                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11645                                + ": not system .apk");
11646                        providers.remove(i);
11647                    }
11648                }
11649            }
11650        }
11651        if (providers != null) {
11652            mSystemThread.installSystemProviders(providers);
11653        }
11654
11655        mConstants.start(mContext.getContentResolver());
11656        mCoreSettingsObserver = new CoreSettingsObserver(this);
11657        mFontScaleSettingObserver = new FontScaleSettingObserver();
11658
11659        // Now that the settings provider is published we can consider sending
11660        // in a rescue party.
11661        RescueParty.onSettingsProviderPublished(mContext);
11662
11663        //mUsageStatsService.monitorPackages();
11664    }
11665
11666    private void startPersistentApps(int matchFlags) {
11667        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11668
11669        synchronized (this) {
11670            try {
11671                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11672                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11673                for (ApplicationInfo app : apps) {
11674                    if (!"android".equals(app.packageName)) {
11675                        addAppLocked(app, null, false, null /* ABI override */);
11676                    }
11677                }
11678            } catch (RemoteException ex) {
11679            }
11680        }
11681    }
11682
11683    /**
11684     * When a user is unlocked, we need to install encryption-unaware providers
11685     * belonging to any running apps.
11686     */
11687    private void installEncryptionUnawareProviders(int userId) {
11688        // We're only interested in providers that are encryption unaware, and
11689        // we don't care about uninstalled apps, since there's no way they're
11690        // running at this point.
11691        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11692
11693        synchronized (this) {
11694            final int NP = mProcessNames.getMap().size();
11695            for (int ip = 0; ip < NP; ip++) {
11696                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11697                final int NA = apps.size();
11698                for (int ia = 0; ia < NA; ia++) {
11699                    final ProcessRecord app = apps.valueAt(ia);
11700                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11701
11702                    final int NG = app.pkgList.size();
11703                    for (int ig = 0; ig < NG; ig++) {
11704                        try {
11705                            final String pkgName = app.pkgList.keyAt(ig);
11706                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11707                                    .getPackageInfo(pkgName, matchFlags, userId);
11708                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11709                                for (ProviderInfo pi : pkgInfo.providers) {
11710                                    // TODO: keep in sync with generateApplicationProvidersLocked
11711                                    final boolean processMatch = Objects.equals(pi.processName,
11712                                            app.processName) || pi.multiprocess;
11713                                    final boolean userMatch = isSingleton(pi.processName,
11714                                            pi.applicationInfo, pi.name, pi.flags)
11715                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
11716                                    if (processMatch && userMatch) {
11717                                        Log.v(TAG, "Installing " + pi);
11718                                        app.thread.scheduleInstallProvider(pi);
11719                                    } else {
11720                                        Log.v(TAG, "Skipping " + pi);
11721                                    }
11722                                }
11723                            }
11724                        } catch (RemoteException ignored) {
11725                        }
11726                    }
11727                }
11728            }
11729        }
11730    }
11731
11732    /**
11733     * Allows apps to retrieve the MIME type of a URI.
11734     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11735     * users, then it does not need permission to access the ContentProvider.
11736     * Either, it needs cross-user uri grants.
11737     *
11738     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11739     *
11740     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11741     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11742     */
11743    public String getProviderMimeType(Uri uri, int userId) {
11744        enforceNotIsolatedCaller("getProviderMimeType");
11745        final String name = uri.getAuthority();
11746        int callingUid = Binder.getCallingUid();
11747        int callingPid = Binder.getCallingPid();
11748        long ident = 0;
11749        boolean clearedIdentity = false;
11750        synchronized (this) {
11751            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11752        }
11753        if (canClearIdentity(callingPid, callingUid, userId)) {
11754            clearedIdentity = true;
11755            ident = Binder.clearCallingIdentity();
11756        }
11757        ContentProviderHolder holder = null;
11758        try {
11759            holder = getContentProviderExternalUnchecked(name, null, userId);
11760            if (holder != null) {
11761                return holder.provider.getType(uri);
11762            }
11763        } catch (RemoteException e) {
11764            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11765            return null;
11766        } catch (Exception e) {
11767            Log.w(TAG, "Exception while determining type of " + uri, e);
11768            return null;
11769        } finally {
11770            // We need to clear the identity to call removeContentProviderExternalUnchecked
11771            if (!clearedIdentity) {
11772                ident = Binder.clearCallingIdentity();
11773            }
11774            try {
11775                if (holder != null) {
11776                    removeContentProviderExternalUnchecked(name, null, userId);
11777                }
11778            } finally {
11779                Binder.restoreCallingIdentity(ident);
11780            }
11781        }
11782
11783        return null;
11784    }
11785
11786    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11787        if (UserHandle.getUserId(callingUid) == userId) {
11788            return true;
11789        }
11790        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11791                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11792                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11793                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11794                return true;
11795        }
11796        return false;
11797    }
11798
11799    // =========================================================
11800    // GLOBAL MANAGEMENT
11801    // =========================================================
11802
11803    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11804            boolean isolated, int isolatedUid) {
11805        String proc = customProcess != null ? customProcess : info.processName;
11806        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11807        final int userId = UserHandle.getUserId(info.uid);
11808        int uid = info.uid;
11809        if (isolated) {
11810            if (isolatedUid == 0) {
11811                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11812                while (true) {
11813                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11814                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11815                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11816                    }
11817                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11818                    mNextIsolatedProcessUid++;
11819                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11820                        // No process for this uid, use it.
11821                        break;
11822                    }
11823                    stepsLeft--;
11824                    if (stepsLeft <= 0) {
11825                        return null;
11826                    }
11827                }
11828            } else {
11829                // Special case for startIsolatedProcess (internal only), where
11830                // the uid of the isolated process is specified by the caller.
11831                uid = isolatedUid;
11832            }
11833
11834            // Register the isolated UID with this application so BatteryStats knows to
11835            // attribute resource usage to the application.
11836            //
11837            // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
11838            // about the process state of the isolated UID *before* it is registered with the
11839            // owning application.
11840            mBatteryStatsService.addIsolatedUid(uid, info.uid);
11841        }
11842        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11843        if (!mBooted && !mBooting
11844                && userId == UserHandle.USER_SYSTEM
11845                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11846            r.persistent = true;
11847            r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11848        }
11849        addProcessNameLocked(r);
11850        return r;
11851    }
11852
11853    private boolean uidOnBackgroundWhitelist(final int uid) {
11854        final int N = mBackgroundUidWhitelist.length;
11855        for (int i = 0; i < N; i++) {
11856            if (uid == mBackgroundUidWhitelist[i]) {
11857                return true;
11858            }
11859        }
11860        return false;
11861    }
11862
11863    final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
11864            String abiOverride) {
11865        ProcessRecord app;
11866        if (!isolated) {
11867            app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
11868                    info.uid, true);
11869        } else {
11870            app = null;
11871        }
11872
11873        if (app == null) {
11874            app = newProcessRecordLocked(info, customProcess, isolated, 0);
11875            updateLruProcessLocked(app, false, null);
11876            updateOomAdjLocked();
11877        }
11878
11879        // This package really, really can not be stopped.
11880        try {
11881            AppGlobals.getPackageManager().setPackageStoppedState(
11882                    info.packageName, false, UserHandle.getUserId(app.uid));
11883        } catch (RemoteException e) {
11884        } catch (IllegalArgumentException e) {
11885            Slog.w(TAG, "Failed trying to unstop package "
11886                    + info.packageName + ": " + e);
11887        }
11888
11889        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11890            app.persistent = true;
11891            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11892        }
11893        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11894            mPersistentStartingProcesses.add(app);
11895            startProcessLocked(app, "added application",
11896                    customProcess != null ? customProcess : app.processName, abiOverride,
11897                    null /* entryPoint */, null /* entryPointArgs */);
11898        }
11899
11900        return app;
11901    }
11902
11903    public void unhandledBack() {
11904        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11905                "unhandledBack()");
11906
11907        synchronized(this) {
11908            final long origId = Binder.clearCallingIdentity();
11909            try {
11910                getFocusedStack().unhandledBackLocked();
11911            } finally {
11912                Binder.restoreCallingIdentity(origId);
11913            }
11914        }
11915    }
11916
11917    public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
11918        enforceNotIsolatedCaller("openContentUri");
11919        final int userId = UserHandle.getCallingUserId();
11920        final Uri uri = Uri.parse(uriString);
11921        String name = uri.getAuthority();
11922        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11923        ParcelFileDescriptor pfd = null;
11924        if (cph != null) {
11925            // We record the binder invoker's uid in thread-local storage before
11926            // going to the content provider to open the file.  Later, in the code
11927            // that handles all permissions checks, we look for this uid and use
11928            // that rather than the Activity Manager's own uid.  The effect is that
11929            // we do the check against the caller's permissions even though it looks
11930            // to the content provider like the Activity Manager itself is making
11931            // the request.
11932            Binder token = new Binder();
11933            sCallerIdentity.set(new Identity(
11934                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11935            try {
11936                pfd = cph.provider.openFile(null, uri, "r", null, token);
11937            } catch (FileNotFoundException e) {
11938                // do nothing; pfd will be returned null
11939            } finally {
11940                // Ensure that whatever happens, we clean up the identity state
11941                sCallerIdentity.remove();
11942                // Ensure we're done with the provider.
11943                removeContentProviderExternalUnchecked(name, null, userId);
11944            }
11945        } else {
11946            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11947        }
11948        return pfd;
11949    }
11950
11951    // Actually is sleeping or shutting down or whatever else in the future
11952    // is an inactive state.
11953    boolean isSleepingOrShuttingDownLocked() {
11954        return isSleepingLocked() || mShuttingDown;
11955    }
11956
11957    boolean isShuttingDownLocked() {
11958        return mShuttingDown;
11959    }
11960
11961    boolean isSleepingLocked() {
11962        return mSleeping;
11963    }
11964
11965    void onWakefulnessChanged(int wakefulness) {
11966        synchronized(this) {
11967            mWakefulness = wakefulness;
11968            updateSleepIfNeededLocked();
11969        }
11970    }
11971
11972    void finishRunningVoiceLocked() {
11973        if (mRunningVoice != null) {
11974            mRunningVoice = null;
11975            mVoiceWakeLock.release();
11976            updateSleepIfNeededLocked();
11977        }
11978    }
11979
11980    void startTimeTrackingFocusedActivityLocked() {
11981        final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
11982        if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
11983            mCurAppTimeTracker.start(resumedActivity.packageName);
11984        }
11985    }
11986
11987    void updateSleepIfNeededLocked() {
11988        if (mSleeping && !shouldSleepLocked()) {
11989            mSleeping = false;
11990            startTimeTrackingFocusedActivityLocked();
11991            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11992            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11993            sendNotifyVrManagerOfSleepState(false);
11994            updateOomAdjLocked();
11995        } else if (!mSleeping && shouldSleepLocked()) {
11996            mSleeping = true;
11997            if (mCurAppTimeTracker != null) {
11998                mCurAppTimeTracker.stop();
11999            }
12000            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
12001            mStackSupervisor.goingToSleepLocked();
12002            sendNotifyVrManagerOfSleepState(true);
12003            updateOomAdjLocked();
12004
12005            // Initialize the wake times of all processes.
12006            checkExcessivePowerUsageLocked(false);
12007            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
12008            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
12009            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
12010        }
12011    }
12012
12013    private boolean shouldSleepLocked() {
12014        // Resume applications while running a voice interactor.
12015        if (mRunningVoice != null) {
12016            return false;
12017        }
12018
12019        // TODO: Transform the lock screen state into a sleep token instead.
12020        switch (mWakefulness) {
12021            case PowerManagerInternal.WAKEFULNESS_AWAKE:
12022            case PowerManagerInternal.WAKEFULNESS_DREAMING:
12023            case PowerManagerInternal.WAKEFULNESS_DOZING:
12024                // Pause applications whenever the lock screen is shown or any sleep
12025                // tokens have been acquired.
12026                return mKeyguardController.isKeyguardShowing() || !mSleepTokens.isEmpty();
12027            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
12028            default:
12029                // If we're asleep then pause applications unconditionally.
12030                return true;
12031        }
12032    }
12033
12034    /** Pokes the task persister. */
12035    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
12036        mRecentTasks.notifyTaskPersisterLocked(task, flush);
12037    }
12038
12039    /** Notifies all listeners when the pinned stack animation ends. */
12040    @Override
12041    public void notifyPinnedStackAnimationEnded() {
12042        mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
12043    }
12044
12045    @Override
12046    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
12047        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
12048    }
12049
12050    @Override
12051    public boolean shutdown(int timeout) {
12052        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
12053                != PackageManager.PERMISSION_GRANTED) {
12054            throw new SecurityException("Requires permission "
12055                    + android.Manifest.permission.SHUTDOWN);
12056        }
12057
12058        boolean timedout = false;
12059
12060        synchronized(this) {
12061            mShuttingDown = true;
12062            updateEventDispatchingLocked();
12063            timedout = mStackSupervisor.shutdownLocked(timeout);
12064        }
12065
12066        mAppOpsService.shutdown();
12067        if (mUsageStatsService != null) {
12068            mUsageStatsService.prepareShutdown();
12069        }
12070        mBatteryStatsService.shutdown();
12071        synchronized (this) {
12072            mProcessStats.shutdownLocked();
12073            notifyTaskPersisterLocked(null, true);
12074        }
12075
12076        return timedout;
12077    }
12078
12079    public final void activitySlept(IBinder token) {
12080        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
12081
12082        final long origId = Binder.clearCallingIdentity();
12083
12084        synchronized (this) {
12085            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12086            if (r != null) {
12087                mStackSupervisor.activitySleptLocked(r);
12088            }
12089        }
12090
12091        Binder.restoreCallingIdentity(origId);
12092    }
12093
12094    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
12095        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
12096        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
12097        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
12098            boolean wasRunningVoice = mRunningVoice != null;
12099            mRunningVoice = session;
12100            if (!wasRunningVoice) {
12101                mVoiceWakeLock.acquire();
12102                updateSleepIfNeededLocked();
12103            }
12104        }
12105    }
12106
12107    private void updateEventDispatchingLocked() {
12108        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
12109    }
12110
12111    @Override
12112    public void setLockScreenShown(boolean showing) {
12113        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
12114                != PackageManager.PERMISSION_GRANTED) {
12115            throw new SecurityException("Requires permission "
12116                    + android.Manifest.permission.DEVICE_POWER);
12117        }
12118
12119        synchronized(this) {
12120            long ident = Binder.clearCallingIdentity();
12121            try {
12122                mKeyguardController.setKeyguardShown(showing);
12123            } finally {
12124                Binder.restoreCallingIdentity(ident);
12125            }
12126        }
12127    }
12128
12129    @Override
12130    public void notifyLockedProfile(@UserIdInt int userId) {
12131        try {
12132            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
12133                throw new SecurityException("Only privileged app can call notifyLockedProfile");
12134            }
12135        } catch (RemoteException ex) {
12136            throw new SecurityException("Fail to check is caller a privileged app", ex);
12137        }
12138
12139        synchronized (this) {
12140            final long ident = Binder.clearCallingIdentity();
12141            try {
12142                if (mUserController.shouldConfirmCredentials(userId)) {
12143                    if (mKeyguardController.isKeyguardLocked()) {
12144                        // Showing launcher to avoid user entering credential twice.
12145                        final int currentUserId = mUserController.getCurrentUserIdLocked();
12146                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
12147                    }
12148                    mStackSupervisor.lockAllProfileTasks(userId);
12149                }
12150            } finally {
12151                Binder.restoreCallingIdentity(ident);
12152            }
12153        }
12154    }
12155
12156    @Override
12157    public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
12158        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
12159        synchronized (this) {
12160            final long ident = Binder.clearCallingIdentity();
12161            try {
12162                mActivityStarter.startConfirmCredentialIntent(intent, options);
12163            } finally {
12164                Binder.restoreCallingIdentity(ident);
12165            }
12166        }
12167    }
12168
12169    @Override
12170    public void stopAppSwitches() {
12171        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12172                != PackageManager.PERMISSION_GRANTED) {
12173            throw new SecurityException("viewquires permission "
12174                    + android.Manifest.permission.STOP_APP_SWITCHES);
12175        }
12176
12177        synchronized(this) {
12178            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
12179                    + APP_SWITCH_DELAY_TIME;
12180            mDidAppSwitch = false;
12181            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12182            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12183            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
12184        }
12185    }
12186
12187    public void resumeAppSwitches() {
12188        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12189                != PackageManager.PERMISSION_GRANTED) {
12190            throw new SecurityException("Requires permission "
12191                    + android.Manifest.permission.STOP_APP_SWITCHES);
12192        }
12193
12194        synchronized(this) {
12195            // Note that we don't execute any pending app switches... we will
12196            // let those wait until either the timeout, or the next start
12197            // activity request.
12198            mAppSwitchesAllowedTime = 0;
12199        }
12200    }
12201
12202    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
12203            int callingPid, int callingUid, String name) {
12204        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
12205            return true;
12206        }
12207
12208        int perm = checkComponentPermission(
12209                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
12210                sourceUid, -1, true);
12211        if (perm == PackageManager.PERMISSION_GRANTED) {
12212            return true;
12213        }
12214
12215        // If the actual IPC caller is different from the logical source, then
12216        // also see if they are allowed to control app switches.
12217        if (callingUid != -1 && callingUid != sourceUid) {
12218            perm = checkComponentPermission(
12219                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
12220                    callingUid, -1, true);
12221            if (perm == PackageManager.PERMISSION_GRANTED) {
12222                return true;
12223            }
12224        }
12225
12226        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
12227        return false;
12228    }
12229
12230    public void setDebugApp(String packageName, boolean waitForDebugger,
12231            boolean persistent) {
12232        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
12233                "setDebugApp()");
12234
12235        long ident = Binder.clearCallingIdentity();
12236        try {
12237            // Note that this is not really thread safe if there are multiple
12238            // callers into it at the same time, but that's not a situation we
12239            // care about.
12240            if (persistent) {
12241                final ContentResolver resolver = mContext.getContentResolver();
12242                Settings.Global.putString(
12243                    resolver, Settings.Global.DEBUG_APP,
12244                    packageName);
12245                Settings.Global.putInt(
12246                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
12247                    waitForDebugger ? 1 : 0);
12248            }
12249
12250            synchronized (this) {
12251                if (!persistent) {
12252                    mOrigDebugApp = mDebugApp;
12253                    mOrigWaitForDebugger = mWaitForDebugger;
12254                }
12255                mDebugApp = packageName;
12256                mWaitForDebugger = waitForDebugger;
12257                mDebugTransient = !persistent;
12258                if (packageName != null) {
12259                    forceStopPackageLocked(packageName, -1, false, false, true, true,
12260                            false, UserHandle.USER_ALL, "set debug app");
12261                }
12262            }
12263        } finally {
12264            Binder.restoreCallingIdentity(ident);
12265        }
12266    }
12267
12268    void setTrackAllocationApp(ApplicationInfo app, String processName) {
12269        synchronized (this) {
12270            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12271            if (!isDebuggable) {
12272                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12273                    throw new SecurityException("Process not debuggable: " + app.packageName);
12274                }
12275            }
12276
12277            mTrackAllocationApp = processName;
12278        }
12279    }
12280
12281    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
12282        synchronized (this) {
12283            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12284            if (!isDebuggable) {
12285                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12286                    throw new SecurityException("Process not debuggable: " + app.packageName);
12287                }
12288            }
12289            mProfileApp = processName;
12290            mProfileFile = profilerInfo.profileFile;
12291            if (mProfileFd != null) {
12292                try {
12293                    mProfileFd.close();
12294                } catch (IOException e) {
12295                }
12296                mProfileFd = null;
12297            }
12298            mProfileFd = profilerInfo.profileFd;
12299            mSamplingInterval = profilerInfo.samplingInterval;
12300            mAutoStopProfiler = profilerInfo.autoStopProfiler;
12301            mStreamingOutput = profilerInfo.streamingOutput;
12302            mProfileType = 0;
12303        }
12304    }
12305
12306    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12307        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12308        if (!isDebuggable) {
12309            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12310                throw new SecurityException("Process not debuggable: " + app.packageName);
12311            }
12312        }
12313        mNativeDebuggingApp = processName;
12314    }
12315
12316    @Override
12317    public void setAlwaysFinish(boolean enabled) {
12318        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12319                "setAlwaysFinish()");
12320
12321        long ident = Binder.clearCallingIdentity();
12322        try {
12323            Settings.Global.putInt(
12324                    mContext.getContentResolver(),
12325                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12326
12327            synchronized (this) {
12328                mAlwaysFinishActivities = enabled;
12329            }
12330        } finally {
12331            Binder.restoreCallingIdentity(ident);
12332        }
12333    }
12334
12335    @Override
12336    public void setActivityController(IActivityController controller, boolean imAMonkey) {
12337        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12338                "setActivityController()");
12339        synchronized (this) {
12340            mController = controller;
12341            mControllerIsAMonkey = imAMonkey;
12342            Watchdog.getInstance().setActivityController(controller);
12343        }
12344    }
12345
12346    @Override
12347    public void setUserIsMonkey(boolean userIsMonkey) {
12348        synchronized (this) {
12349            synchronized (mPidsSelfLocked) {
12350                final int callingPid = Binder.getCallingPid();
12351                ProcessRecord proc = mPidsSelfLocked.get(callingPid);
12352                if (proc == null) {
12353                    throw new SecurityException("Unknown process: " + callingPid);
12354                }
12355                if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
12356                    throw new SecurityException("Only an instrumentation process "
12357                            + "with a UiAutomation can call setUserIsMonkey");
12358                }
12359            }
12360            mUserIsMonkey = userIsMonkey;
12361        }
12362    }
12363
12364    @Override
12365    public boolean isUserAMonkey() {
12366        synchronized (this) {
12367            // If there is a controller also implies the user is a monkey.
12368            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12369        }
12370    }
12371
12372    /**
12373     * @deprecated This method is only used by a few internal components and it will soon be
12374     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12375     * No new code should be calling it.
12376     */
12377    @Deprecated
12378    public void requestBugReport(int bugreportType) {
12379        String extraOptions = null;
12380        switch (bugreportType) {
12381            case ActivityManager.BUGREPORT_OPTION_FULL:
12382                // Default options.
12383                break;
12384            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12385                extraOptions = "bugreportplus";
12386                break;
12387            case ActivityManager.BUGREPORT_OPTION_REMOTE:
12388                extraOptions = "bugreportremote";
12389                break;
12390            case ActivityManager.BUGREPORT_OPTION_WEAR:
12391                extraOptions = "bugreportwear";
12392                break;
12393            case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
12394                extraOptions = "bugreporttelephony";
12395                break;
12396            default:
12397                throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12398                        + bugreportType);
12399        }
12400        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12401        if (extraOptions != null) {
12402            SystemProperties.set("dumpstate.options", extraOptions);
12403        }
12404        SystemProperties.set("ctl.start", "bugreport");
12405    }
12406
12407    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12408        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12409    }
12410
12411    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12412        if (r != null && (r.instr != null || r.usingWrapper)) {
12413            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12414        }
12415        return KEY_DISPATCHING_TIMEOUT;
12416    }
12417
12418    @Override
12419    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12420        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12421                != PackageManager.PERMISSION_GRANTED) {
12422            throw new SecurityException("Requires permission "
12423                    + android.Manifest.permission.FILTER_EVENTS);
12424        }
12425        ProcessRecord proc;
12426        long timeout;
12427        synchronized (this) {
12428            synchronized (mPidsSelfLocked) {
12429                proc = mPidsSelfLocked.get(pid);
12430            }
12431            timeout = getInputDispatchingTimeoutLocked(proc);
12432        }
12433
12434        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12435            return -1;
12436        }
12437
12438        return timeout;
12439    }
12440
12441    /**
12442     * Handle input dispatching timeouts.
12443     * Returns whether input dispatching should be aborted or not.
12444     */
12445    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12446            final ActivityRecord activity, final ActivityRecord parent,
12447            final boolean aboveSystem, String reason) {
12448        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12449                != PackageManager.PERMISSION_GRANTED) {
12450            throw new SecurityException("Requires permission "
12451                    + android.Manifest.permission.FILTER_EVENTS);
12452        }
12453
12454        final String annotation;
12455        if (reason == null) {
12456            annotation = "Input dispatching timed out";
12457        } else {
12458            annotation = "Input dispatching timed out (" + reason + ")";
12459        }
12460
12461        if (proc != null) {
12462            synchronized (this) {
12463                if (proc.debugging) {
12464                    return false;
12465                }
12466
12467                if (mDidDexOpt) {
12468                    // Give more time since we were dexopting.
12469                    mDidDexOpt = false;
12470                    return false;
12471                }
12472
12473                if (proc.instr != null) {
12474                    Bundle info = new Bundle();
12475                    info.putString("shortMsg", "keyDispatchingTimedOut");
12476                    info.putString("longMsg", annotation);
12477                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12478                    return true;
12479                }
12480            }
12481            mHandler.post(new Runnable() {
12482                @Override
12483                public void run() {
12484                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12485                }
12486            });
12487        }
12488
12489        return true;
12490    }
12491
12492    @Override
12493    public Bundle getAssistContextExtras(int requestType) {
12494        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12495                null, null, true /* focused */, true /* newSessionId */,
12496                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12497        if (pae == null) {
12498            return null;
12499        }
12500        synchronized (pae) {
12501            while (!pae.haveResult) {
12502                try {
12503                    pae.wait();
12504                } catch (InterruptedException e) {
12505                }
12506            }
12507        }
12508        synchronized (this) {
12509            buildAssistBundleLocked(pae, pae.result);
12510            mPendingAssistExtras.remove(pae);
12511            mUiHandler.removeCallbacks(pae);
12512        }
12513        return pae.extras;
12514    }
12515
12516    @Override
12517    public boolean isAssistDataAllowedOnCurrentActivity() {
12518        int userId;
12519        synchronized (this) {
12520            final ActivityStack focusedStack = getFocusedStack();
12521            if (focusedStack == null || focusedStack.isAssistantStack()) {
12522                return false;
12523            }
12524
12525            final ActivityRecord activity = focusedStack.topActivity();
12526            if (activity == null) {
12527                return false;
12528            }
12529            userId = activity.userId;
12530        }
12531        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12532                Context.DEVICE_POLICY_SERVICE);
12533        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12534    }
12535
12536    @Override
12537    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12538        long ident = Binder.clearCallingIdentity();
12539        try {
12540            synchronized (this) {
12541                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12542                ActivityRecord top = getFocusedStack().topActivity();
12543                if (top != caller) {
12544                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12545                            + " is not current top " + top);
12546                    return false;
12547                }
12548                if (!top.nowVisible) {
12549                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12550                            + " is not visible");
12551                    return false;
12552                }
12553            }
12554            return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
12555                    token);
12556        } finally {
12557            Binder.restoreCallingIdentity(ident);
12558        }
12559    }
12560
12561    @Override
12562    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12563            Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
12564        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12565                activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
12566                PENDING_ASSIST_EXTRAS_LONG_TIMEOUT) != null;
12567    }
12568
12569    @Override
12570    public boolean requestAutoFillData(IResultReceiver receiver, Bundle receiverExtras,
12571            IBinder activityToken) {
12572        // NOTE: we could always use ActivityManager.ASSIST_CONTEXT_FULL and let ActivityThread
12573        // rely on the flags to decide whether the handleRequestAssistContextExtras() is for
12574        // auto-fill, but it's safer to explicitly use new AutoFill types, in case the Assist
12575        // requests use flags in the future as well (since their flags value might collide with the
12576        // auto-fill flag values).
12577        return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTO_FILL, null, null,
12578                receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
12579                null, PENDING_AUTO_FILL_ASSIST_STRUCTURE_TIMEOUT) != null;
12580    }
12581
12582    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12583            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12584            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12585        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12586                "enqueueAssistContext()");
12587
12588        synchronized (this) {
12589            ActivityRecord activity = getFocusedStack().topActivity();
12590            if (activity == null) {
12591                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12592                return null;
12593            }
12594            if (activity.app == null || activity.app.thread == null) {
12595                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12596                return null;
12597            }
12598            if (focused) {
12599                if (activityToken != null) {
12600                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12601                    if (activity != caller) {
12602                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12603                                + " is not current top " + activity);
12604                        return null;
12605                    }
12606                }
12607            } else {
12608                activity = ActivityRecord.forTokenLocked(activityToken);
12609                if (activity == null) {
12610                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12611                            + " couldn't be found");
12612                    return null;
12613                }
12614            }
12615
12616            PendingAssistExtras pae;
12617            Bundle extras = new Bundle();
12618            if (args != null) {
12619                extras.putAll(args);
12620            }
12621            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12622            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12623
12624            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12625                    userHandle);
12626
12627            // Increment the sessionId if necessary
12628            if (newSessionId) {
12629                mViSessionId++;
12630            }
12631            try {
12632                activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
12633                        mViSessionId);
12634                mPendingAssistExtras.add(pae);
12635                mUiHandler.postDelayed(pae, timeout);
12636            } catch (RemoteException e) {
12637                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12638                return null;
12639            }
12640            return pae;
12641        }
12642    }
12643
12644    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12645        IResultReceiver receiver;
12646        synchronized (this) {
12647            mPendingAssistExtras.remove(pae);
12648            receiver = pae.receiver;
12649        }
12650        if (receiver != null) {
12651            // Caller wants result sent back to them.
12652            Bundle sendBundle = new Bundle();
12653            // At least return the receiver extras
12654            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12655                    pae.receiverExtras);
12656            try {
12657                pae.receiver.send(0, sendBundle);
12658            } catch (RemoteException e) {
12659            }
12660        }
12661    }
12662
12663    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12664        if (result != null) {
12665            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12666        }
12667        if (pae.hint != null) {
12668            pae.extras.putBoolean(pae.hint, true);
12669        }
12670    }
12671
12672    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12673            AssistContent content, Uri referrer) {
12674        PendingAssistExtras pae = (PendingAssistExtras)token;
12675        synchronized (pae) {
12676            pae.result = extras;
12677            pae.structure = structure;
12678            pae.content = content;
12679            if (referrer != null) {
12680                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12681            }
12682            pae.haveResult = true;
12683            pae.notifyAll();
12684            if (pae.intent == null && pae.receiver == null) {
12685                // Caller is just waiting for the result.
12686                return;
12687            }
12688        }
12689
12690        // We are now ready to launch the assist activity.
12691        IResultReceiver sendReceiver = null;
12692        Bundle sendBundle = null;
12693        synchronized (this) {
12694            buildAssistBundleLocked(pae, extras);
12695            boolean exists = mPendingAssistExtras.remove(pae);
12696            mUiHandler.removeCallbacks(pae);
12697            if (!exists) {
12698                // Timed out.
12699                return;
12700            }
12701            if ((sendReceiver=pae.receiver) != null) {
12702                // Caller wants result sent back to them.
12703                sendBundle = new Bundle();
12704                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12705                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12706                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12707                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12708                        pae.receiverExtras);
12709            }
12710        }
12711        if (sendReceiver != null) {
12712            try {
12713                sendReceiver.send(0, sendBundle);
12714            } catch (RemoteException e) {
12715            }
12716            return;
12717        }
12718
12719        long ident = Binder.clearCallingIdentity();
12720        try {
12721            pae.intent.replaceExtras(pae.extras);
12722            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12723                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12724                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12725            closeSystemDialogs("assist");
12726            try {
12727                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12728            } catch (ActivityNotFoundException e) {
12729                Slog.w(TAG, "No activity to handle assist action.", e);
12730            }
12731        } finally {
12732            Binder.restoreCallingIdentity(ident);
12733        }
12734    }
12735
12736    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12737            Bundle args) {
12738        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12739                true /* focused */, true /* newSessionId */, userHandle, args,
12740                PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12741    }
12742
12743    public void registerProcessObserver(IProcessObserver observer) {
12744        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12745                "registerProcessObserver()");
12746        synchronized (this) {
12747            mProcessObservers.register(observer);
12748        }
12749    }
12750
12751    @Override
12752    public void unregisterProcessObserver(IProcessObserver observer) {
12753        synchronized (this) {
12754            mProcessObservers.unregister(observer);
12755        }
12756    }
12757
12758    @Override
12759    public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
12760            String callingPackage) {
12761        if (!hasUsageStatsPermission(callingPackage)) {
12762            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
12763                    "registerUidObserver");
12764        }
12765        synchronized (this) {
12766            mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
12767                    callingPackage, which, cutpoint));
12768        }
12769    }
12770
12771    @Override
12772    public void unregisterUidObserver(IUidObserver observer) {
12773        synchronized (this) {
12774            mUidObservers.unregister(observer);
12775        }
12776    }
12777
12778    @Override
12779    public boolean convertFromTranslucent(IBinder token) {
12780        final long origId = Binder.clearCallingIdentity();
12781        try {
12782            synchronized (this) {
12783                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12784                if (r == null) {
12785                    return false;
12786                }
12787                final boolean translucentChanged = r.changeWindowTranslucency(true);
12788                if (translucentChanged) {
12789                    r.getStack().releaseBackgroundResources(r);
12790                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12791                }
12792                mWindowManager.setAppFullscreen(token, true);
12793                return translucentChanged;
12794            }
12795        } finally {
12796            Binder.restoreCallingIdentity(origId);
12797        }
12798    }
12799
12800    @Override
12801    public boolean convertToTranslucent(IBinder token, Bundle options) {
12802        final long origId = Binder.clearCallingIdentity();
12803        try {
12804            synchronized (this) {
12805                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12806                if (r == null) {
12807                    return false;
12808                }
12809                int index = r.task.mActivities.lastIndexOf(r);
12810                if (index > 0) {
12811                    ActivityRecord under = r.task.mActivities.get(index - 1);
12812                    under.returningOptions = ActivityOptions.fromBundle(options);
12813                }
12814                final boolean translucentChanged = r.changeWindowTranslucency(false);
12815                if (translucentChanged) {
12816                    r.getStack().convertActivityToTranslucent(r);
12817                }
12818                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12819                mWindowManager.setAppFullscreen(token, false);
12820                return translucentChanged;
12821            }
12822        } finally {
12823            Binder.restoreCallingIdentity(origId);
12824        }
12825    }
12826
12827    @Override
12828    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12829        final long origId = Binder.clearCallingIdentity();
12830        try {
12831            synchronized (this) {
12832                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12833                if (r != null) {
12834                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12835                }
12836            }
12837            return false;
12838        } finally {
12839            Binder.restoreCallingIdentity(origId);
12840        }
12841    }
12842
12843    @Override
12844    public boolean isBackgroundVisibleBehind(IBinder token) {
12845        final long origId = Binder.clearCallingIdentity();
12846        try {
12847            synchronized (this) {
12848                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12849                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12850                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12851                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12852                return visible;
12853            }
12854        } finally {
12855            Binder.restoreCallingIdentity(origId);
12856        }
12857    }
12858
12859    @Override
12860    public Bundle getActivityOptions(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                    final ActivityOptions activityOptions = r.pendingOptions;
12867                    r.pendingOptions = null;
12868                    return activityOptions == null ? null : activityOptions.toBundle();
12869                }
12870                return null;
12871            }
12872        } finally {
12873            Binder.restoreCallingIdentity(origId);
12874        }
12875    }
12876
12877    @Override
12878    public void setImmersive(IBinder token, boolean immersive) {
12879        synchronized(this) {
12880            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12881            if (r == null) {
12882                throw new IllegalArgumentException();
12883            }
12884            r.immersive = immersive;
12885
12886            // update associated state if we're frontmost
12887            if (r == mStackSupervisor.getResumedActivityLocked()) {
12888                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12889                applyUpdateLockStateLocked(r);
12890            }
12891        }
12892    }
12893
12894    @Override
12895    public boolean isImmersive(IBinder token) {
12896        synchronized (this) {
12897            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12898            if (r == null) {
12899                throw new IllegalArgumentException();
12900            }
12901            return r.immersive;
12902        }
12903    }
12904
12905    public void setVrThread(int tid) {
12906        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12907            throw new UnsupportedOperationException("VR mode not supported on this device!");
12908        }
12909
12910        synchronized (this) {
12911            ProcessRecord proc;
12912            synchronized (mPidsSelfLocked) {
12913                final int pid = Binder.getCallingPid();
12914                proc = mPidsSelfLocked.get(pid);
12915
12916                if (proc != null && mInVrMode && tid >= 0) {
12917                    // ensure the tid belongs to the process
12918                    if (!Process.isThreadInProcess(pid, tid)) {
12919                        throw new IllegalArgumentException("VR thread does not belong to process");
12920                    }
12921
12922                    // reset existing VR thread to CFS if this thread still exists and belongs to
12923                    // the calling process
12924                    if (proc.vrThreadTid != 0
12925                            && Process.isThreadInProcess(pid, proc.vrThreadTid)) {
12926                        try {
12927                            Process.setThreadScheduler(proc.vrThreadTid, Process.SCHED_OTHER, 0);
12928                        } catch (IllegalArgumentException e) {
12929                            // Ignore this.  Only occurs in race condition where previous VR thread
12930                            // was destroyed during this method call.
12931                        }
12932                    }
12933
12934                    proc.vrThreadTid = tid;
12935
12936                    // promote to FIFO now if the tid is non-zero
12937                    try {
12938                        if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
12939                            proc.vrThreadTid > 0) {
12940                            Process.setThreadScheduler(proc.vrThreadTid,
12941                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12942                        }
12943                    } catch (IllegalArgumentException e) {
12944                        Slog.e(TAG, "Failed to set scheduling policy, thread does"
12945                               + " not exist:\n" + e);
12946                    }
12947                }
12948            }
12949        }
12950    }
12951
12952    @Override
12953    public void setRenderThread(int tid) {
12954        synchronized (this) {
12955            ProcessRecord proc;
12956            synchronized (mPidsSelfLocked) {
12957                int pid = Binder.getCallingPid();
12958                proc = mPidsSelfLocked.get(pid);
12959                if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
12960                    // ensure the tid belongs to the process
12961                    if (!Process.isThreadInProcess(pid, tid)) {
12962                        throw new IllegalArgumentException(
12963                            "Render thread does not belong to process");
12964                    }
12965                    proc.renderThreadTid = tid;
12966                    if (DEBUG_OOM_ADJ) {
12967                        Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
12968                    }
12969                    // promote to FIFO now
12970                    if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
12971                        if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
12972                        if (mUseFifoUiScheduling) {
12973                            Process.setThreadScheduler(proc.renderThreadTid,
12974                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12975                        } else {
12976                            Process.setThreadPriority(proc.renderThreadTid, -10);
12977                        }
12978                    }
12979                } else {
12980                    if (DEBUG_OOM_ADJ) {
12981                        Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
12982                               "PID: " + pid + ", TID: " + tid + " FIFO: " +
12983                               mUseFifoUiScheduling);
12984                    }
12985                }
12986            }
12987        }
12988    }
12989
12990    @Override
12991    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12992        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12993            throw new UnsupportedOperationException("VR mode not supported on this device!");
12994        }
12995
12996        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12997
12998        ActivityRecord r;
12999        synchronized (this) {
13000            r = ActivityRecord.isInStackLocked(token);
13001        }
13002
13003        if (r == null) {
13004            throw new IllegalArgumentException();
13005        }
13006
13007        int err;
13008        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
13009                VrManagerInternal.NO_ERROR) {
13010            return err;
13011        }
13012
13013        synchronized(this) {
13014            r.requestedVrComponent = (enabled) ? packageName : null;
13015
13016            // Update associated state if this activity is currently focused
13017            if (r == mStackSupervisor.getResumedActivityLocked()) {
13018                applyUpdateVrModeLocked(r);
13019            }
13020            return 0;
13021        }
13022    }
13023
13024    @Override
13025    public boolean isVrModePackageEnabled(ComponentName packageName) {
13026        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13027            throw new UnsupportedOperationException("VR mode not supported on this device!");
13028        }
13029
13030        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13031
13032        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
13033                VrManagerInternal.NO_ERROR;
13034    }
13035
13036    public boolean isTopActivityImmersive() {
13037        enforceNotIsolatedCaller("startActivity");
13038        synchronized (this) {
13039            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
13040            return (r != null) ? r.immersive : false;
13041        }
13042    }
13043
13044    @Override
13045    public boolean isTopOfTask(IBinder token) {
13046        synchronized (this) {
13047            ActivityRecord r = ActivityRecord.isInStackLocked(token);
13048            if (r == null) {
13049                throw new IllegalArgumentException();
13050            }
13051            return r.task.getTopActivity() == r;
13052        }
13053    }
13054
13055    @Override
13056    public void setHasTopUi(boolean hasTopUi) throws RemoteException {
13057        if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
13058            String msg = "Permission Denial: setHasTopUi() from pid="
13059                    + Binder.getCallingPid()
13060                    + ", uid=" + Binder.getCallingUid()
13061                    + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
13062            Slog.w(TAG, msg);
13063            throw new SecurityException(msg);
13064        }
13065        final int pid = Binder.getCallingPid();
13066        final long origId = Binder.clearCallingIdentity();
13067        try {
13068            synchronized (this) {
13069                boolean changed = false;
13070                ProcessRecord pr;
13071                synchronized (mPidsSelfLocked) {
13072                    pr = mPidsSelfLocked.get(pid);
13073                    if (pr == null) {
13074                        Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
13075                        return;
13076                    }
13077                    if (pr.hasTopUi != hasTopUi) {
13078                        Slog.i(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
13079                        pr.hasTopUi = hasTopUi;
13080                        changed = true;
13081                    }
13082                }
13083                if (changed) {
13084                    updateOomAdjLocked(pr);
13085                }
13086            }
13087        } finally {
13088            Binder.restoreCallingIdentity(origId);
13089        }
13090    }
13091
13092    public final void enterSafeMode() {
13093        synchronized(this) {
13094            // It only makes sense to do this before the system is ready
13095            // and started launching other packages.
13096            if (!mSystemReady) {
13097                try {
13098                    AppGlobals.getPackageManager().enterSafeMode();
13099                } catch (RemoteException e) {
13100                }
13101            }
13102
13103            mSafeMode = true;
13104        }
13105    }
13106
13107    public final void showSafeModeOverlay() {
13108        View v = LayoutInflater.from(mContext).inflate(
13109                com.android.internal.R.layout.safe_mode, null);
13110        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
13111        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
13112        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
13113        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
13114        lp.gravity = Gravity.BOTTOM | Gravity.START;
13115        lp.format = v.getBackground().getOpacity();
13116        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
13117                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
13118        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
13119        ((WindowManager)mContext.getSystemService(
13120                Context.WINDOW_SERVICE)).addView(v, lp);
13121    }
13122
13123    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
13124        if (sender != null && !(sender instanceof PendingIntentRecord)) {
13125            return;
13126        }
13127        final PendingIntentRecord rec = (PendingIntentRecord)sender;
13128        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13129        synchronized (stats) {
13130            if (mBatteryStatsService.isOnBattery()) {
13131                mBatteryStatsService.enforceCallingPermission();
13132                int MY_UID = Binder.getCallingUid();
13133                final int uid;
13134                if (sender == null) {
13135                    uid = sourceUid;
13136                } else {
13137                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
13138                }
13139                BatteryStatsImpl.Uid.Pkg pkg =
13140                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
13141                            sourcePkg != null ? sourcePkg : rec.key.packageName);
13142                pkg.noteWakeupAlarmLocked(tag);
13143            }
13144        }
13145    }
13146
13147    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
13148        if (sender != null && !(sender instanceof PendingIntentRecord)) {
13149            return;
13150        }
13151        final PendingIntentRecord rec = (PendingIntentRecord)sender;
13152        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13153        synchronized (stats) {
13154            mBatteryStatsService.enforceCallingPermission();
13155            int MY_UID = Binder.getCallingUid();
13156            final int uid;
13157            if (sender == null) {
13158                uid = sourceUid;
13159            } else {
13160                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
13161            }
13162            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
13163        }
13164    }
13165
13166    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
13167        if (sender != null && !(sender instanceof PendingIntentRecord)) {
13168            return;
13169        }
13170        final PendingIntentRecord rec = (PendingIntentRecord)sender;
13171        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13172        synchronized (stats) {
13173            mBatteryStatsService.enforceCallingPermission();
13174            int MY_UID = Binder.getCallingUid();
13175            final int uid;
13176            if (sender == null) {
13177                uid = sourceUid;
13178            } else {
13179                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
13180            }
13181            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
13182        }
13183    }
13184
13185    public boolean killPids(int[] pids, String pReason, boolean secure) {
13186        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
13187            throw new SecurityException("killPids only available to the system");
13188        }
13189        String reason = (pReason == null) ? "Unknown" : pReason;
13190        // XXX Note: don't acquire main activity lock here, because the window
13191        // manager calls in with its locks held.
13192
13193        boolean killed = false;
13194        synchronized (mPidsSelfLocked) {
13195            int worstType = 0;
13196            for (int i=0; i<pids.length; i++) {
13197                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13198                if (proc != null) {
13199                    int type = proc.setAdj;
13200                    if (type > worstType) {
13201                        worstType = type;
13202                    }
13203                }
13204            }
13205
13206            // If the worst oom_adj is somewhere in the cached proc LRU range,
13207            // then constrain it so we will kill all cached procs.
13208            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
13209                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
13210                worstType = ProcessList.CACHED_APP_MIN_ADJ;
13211            }
13212
13213            // If this is not a secure call, don't let it kill processes that
13214            // are important.
13215            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
13216                worstType = ProcessList.SERVICE_ADJ;
13217            }
13218
13219            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
13220            for (int i=0; i<pids.length; i++) {
13221                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13222                if (proc == null) {
13223                    continue;
13224                }
13225                int adj = proc.setAdj;
13226                if (adj >= worstType && !proc.killedByAm) {
13227                    proc.kill(reason, true);
13228                    killed = true;
13229                }
13230            }
13231        }
13232        return killed;
13233    }
13234
13235    @Override
13236    public void killUid(int appId, int userId, String reason) {
13237        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
13238        synchronized (this) {
13239            final long identity = Binder.clearCallingIdentity();
13240            try {
13241                killPackageProcessesLocked(null, appId, userId,
13242                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
13243                        reason != null ? reason : "kill uid");
13244            } finally {
13245                Binder.restoreCallingIdentity(identity);
13246            }
13247        }
13248    }
13249
13250    @Override
13251    public boolean killProcessesBelowForeground(String reason) {
13252        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
13253            throw new SecurityException("killProcessesBelowForeground() only available to system");
13254        }
13255
13256        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
13257    }
13258
13259    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
13260        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
13261            throw new SecurityException("killProcessesBelowAdj() only available to system");
13262        }
13263
13264        boolean killed = false;
13265        synchronized (mPidsSelfLocked) {
13266            final int size = mPidsSelfLocked.size();
13267            for (int i = 0; i < size; i++) {
13268                final int pid = mPidsSelfLocked.keyAt(i);
13269                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13270                if (proc == null) continue;
13271
13272                final int adj = proc.setAdj;
13273                if (adj > belowAdj && !proc.killedByAm) {
13274                    proc.kill(reason, true);
13275                    killed = true;
13276                }
13277            }
13278        }
13279        return killed;
13280    }
13281
13282    @Override
13283    public void hang(final IBinder who, boolean allowRestart) {
13284        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13285                != PackageManager.PERMISSION_GRANTED) {
13286            throw new SecurityException("Requires permission "
13287                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13288        }
13289
13290        final IBinder.DeathRecipient death = new DeathRecipient() {
13291            @Override
13292            public void binderDied() {
13293                synchronized (this) {
13294                    notifyAll();
13295                }
13296            }
13297        };
13298
13299        try {
13300            who.linkToDeath(death, 0);
13301        } catch (RemoteException e) {
13302            Slog.w(TAG, "hang: given caller IBinder is already dead.");
13303            return;
13304        }
13305
13306        synchronized (this) {
13307            Watchdog.getInstance().setAllowRestart(allowRestart);
13308            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
13309            synchronized (death) {
13310                while (who.isBinderAlive()) {
13311                    try {
13312                        death.wait();
13313                    } catch (InterruptedException e) {
13314                    }
13315                }
13316            }
13317            Watchdog.getInstance().setAllowRestart(true);
13318        }
13319    }
13320
13321    @Override
13322    public void restart() {
13323        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13324                != PackageManager.PERMISSION_GRANTED) {
13325            throw new SecurityException("Requires permission "
13326                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13327        }
13328
13329        Log.i(TAG, "Sending shutdown broadcast...");
13330
13331        BroadcastReceiver br = new BroadcastReceiver() {
13332            @Override public void onReceive(Context context, Intent intent) {
13333                // Now the broadcast is done, finish up the low-level shutdown.
13334                Log.i(TAG, "Shutting down activity manager...");
13335                shutdown(10000);
13336                Log.i(TAG, "Shutdown complete, restarting!");
13337                Process.killProcess(Process.myPid());
13338                System.exit(10);
13339            }
13340        };
13341
13342        // First send the high-level shut down broadcast.
13343        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13344        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13345        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13346        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13347        mContext.sendOrderedBroadcastAsUser(intent,
13348                UserHandle.ALL, null, br, mHandler, 0, null, null);
13349        */
13350        br.onReceive(mContext, intent);
13351    }
13352
13353    private long getLowRamTimeSinceIdle(long now) {
13354        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13355    }
13356
13357    @Override
13358    public void performIdleMaintenance() {
13359        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13360                != PackageManager.PERMISSION_GRANTED) {
13361            throw new SecurityException("Requires permission "
13362                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13363        }
13364
13365        synchronized (this) {
13366            final long now = SystemClock.uptimeMillis();
13367            final long timeSinceLastIdle = now - mLastIdleTime;
13368            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13369            mLastIdleTime = now;
13370            mLowRamTimeSinceLastIdle = 0;
13371            if (mLowRamStartTime != 0) {
13372                mLowRamStartTime = now;
13373            }
13374
13375            StringBuilder sb = new StringBuilder(128);
13376            sb.append("Idle maintenance over ");
13377            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13378            sb.append(" low RAM for ");
13379            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13380            Slog.i(TAG, sb.toString());
13381
13382            // If at least 1/3 of our time since the last idle period has been spent
13383            // with RAM low, then we want to kill processes.
13384            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
13385
13386            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13387                ProcessRecord proc = mLruProcesses.get(i);
13388                if (proc.notCachedSinceIdle) {
13389                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
13390                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
13391                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
13392                        if (doKilling && proc.initialIdlePss != 0
13393                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
13394                            sb = new StringBuilder(128);
13395                            sb.append("Kill");
13396                            sb.append(proc.processName);
13397                            sb.append(" in idle maint: pss=");
13398                            sb.append(proc.lastPss);
13399                            sb.append(", swapPss=");
13400                            sb.append(proc.lastSwapPss);
13401                            sb.append(", initialPss=");
13402                            sb.append(proc.initialIdlePss);
13403                            sb.append(", period=");
13404                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13405                            sb.append(", lowRamPeriod=");
13406                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13407                            Slog.wtfQuiet(TAG, sb.toString());
13408                            proc.kill("idle maint (pss " + proc.lastPss
13409                                    + " from " + proc.initialIdlePss + ")", true);
13410                        }
13411                    }
13412                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
13413                        && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
13414                    proc.notCachedSinceIdle = true;
13415                    proc.initialIdlePss = 0;
13416                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
13417                            mTestPssMode, isSleepingLocked(), now);
13418                }
13419            }
13420
13421            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
13422            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
13423        }
13424    }
13425
13426    @Override
13427    public void sendIdleJobTrigger() {
13428        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13429                != PackageManager.PERMISSION_GRANTED) {
13430            throw new SecurityException("Requires permission "
13431                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13432        }
13433
13434        final long ident = Binder.clearCallingIdentity();
13435        try {
13436            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
13437                    .setPackage("android")
13438                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13439            broadcastIntent(null, intent, null, null, 0, null, null, null,
13440                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
13441        } finally {
13442            Binder.restoreCallingIdentity(ident);
13443        }
13444    }
13445
13446    private void retrieveSettings() {
13447        final ContentResolver resolver = mContext.getContentResolver();
13448        final boolean freeformWindowManagement =
13449                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
13450                        || Settings.Global.getInt(
13451                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
13452        final boolean supportsPictureInPicture =
13453                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
13454
13455        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
13456        final boolean supportsSplitScreenMultiWindow =
13457                ActivityManager.supportsSplitScreenMultiWindow();
13458        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
13459        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
13460        final boolean alwaysFinishActivities =
13461                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
13462        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
13463        final boolean forceResizable = Settings.Global.getInt(
13464                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
13465        final boolean supportsLeanbackOnly =
13466                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
13467
13468        // Transfer any global setting for forcing RTL layout, into a System Property
13469        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
13470
13471        final Configuration configuration = new Configuration();
13472        Settings.System.getConfiguration(resolver, configuration);
13473        if (forceRtl) {
13474            // This will take care of setting the correct layout direction flags
13475            configuration.setLayoutDirection(configuration.locale);
13476        }
13477
13478        synchronized (this) {
13479            mDebugApp = mOrigDebugApp = debugApp;
13480            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
13481            mAlwaysFinishActivities = alwaysFinishActivities;
13482            mSupportsLeanbackOnly = supportsLeanbackOnly;
13483            mForceResizableActivities = forceResizable;
13484            if (supportsMultiWindow || forceResizable) {
13485                mSupportsMultiWindow = true;
13486                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
13487            } else {
13488                mSupportsMultiWindow = false;
13489                mSupportsFreeformWindowManagement = false;
13490            }
13491            mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
13492            mSupportsPictureInPicture = supportsPictureInPicture;
13493            mWindowManager.setForceResizableTasks(mForceResizableActivities);
13494            mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
13495            // This happens before any activities are started, so we can change global configuration
13496            // in-place.
13497            updateConfigurationLocked(configuration, null, true);
13498            final Configuration globalConfig = getGlobalConfiguration();
13499            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
13500
13501            // Load resources only after the current configuration has been set.
13502            final Resources res = mContext.getResources();
13503            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
13504            mThumbnailWidth = res.getDimensionPixelSize(
13505                    com.android.internal.R.dimen.thumbnail_width);
13506            mThumbnailHeight = res.getDimensionPixelSize(
13507                    com.android.internal.R.dimen.thumbnail_height);
13508            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
13509                    com.android.internal.R.string.config_appsNotReportingCrashes));
13510            mUserController.mUserSwitchUiEnabled = !res.getBoolean(
13511                    com.android.internal.R.bool.config_customUserSwitchUi);
13512            if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
13513                mFullscreenThumbnailScale = (float) res
13514                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
13515                    (float) globalConfig.screenWidthDp;
13516            } else {
13517                mFullscreenThumbnailScale = res.getFraction(
13518                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13519            }
13520        }
13521    }
13522
13523    public void systemReady(final Runnable goingCallback, BootTimingsTraceLog traceLog) {
13524        traceLog.traceBegin("PhaseActivityManagerReady");
13525        synchronized(this) {
13526            if (mSystemReady) {
13527                // If we're done calling all the receivers, run the next "boot phase" passed in
13528                // by the SystemServer
13529                if (goingCallback != null) {
13530                    goingCallback.run();
13531                }
13532                return;
13533            }
13534
13535            mLocalDeviceIdleController
13536                    = LocalServices.getService(DeviceIdleController.LocalService.class);
13537            mAssistUtils = new AssistUtils(mContext);
13538
13539            // Make sure we have the current profile info, since it is needed for security checks.
13540            mUserController.onSystemReady();
13541            mRecentTasks.onSystemReadyLocked();
13542            mAppOpsService.systemReady();
13543            mSystemReady = true;
13544        }
13545
13546        ArrayList<ProcessRecord> procsToKill = null;
13547        synchronized(mPidsSelfLocked) {
13548            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13549                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13550                if (!isAllowedWhileBooting(proc.info)){
13551                    if (procsToKill == null) {
13552                        procsToKill = new ArrayList<ProcessRecord>();
13553                    }
13554                    procsToKill.add(proc);
13555                }
13556            }
13557        }
13558
13559        synchronized(this) {
13560            if (procsToKill != null) {
13561                for (int i=procsToKill.size()-1; i>=0; i--) {
13562                    ProcessRecord proc = procsToKill.get(i);
13563                    Slog.i(TAG, "Removing system update proc: " + proc);
13564                    removeProcessLocked(proc, true, false, "system update done");
13565                }
13566            }
13567
13568            // Now that we have cleaned up any update processes, we
13569            // are ready to start launching real processes and know that
13570            // we won't trample on them any more.
13571            mProcessesReady = true;
13572        }
13573
13574        Slog.i(TAG, "System now ready");
13575        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13576            SystemClock.uptimeMillis());
13577
13578        synchronized(this) {
13579            // Make sure we have no pre-ready processes sitting around.
13580
13581            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13582                ResolveInfo ri = mContext.getPackageManager()
13583                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13584                                STOCK_PM_FLAGS);
13585                CharSequence errorMsg = null;
13586                if (ri != null) {
13587                    ActivityInfo ai = ri.activityInfo;
13588                    ApplicationInfo app = ai.applicationInfo;
13589                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13590                        mTopAction = Intent.ACTION_FACTORY_TEST;
13591                        mTopData = null;
13592                        mTopComponent = new ComponentName(app.packageName,
13593                                ai.name);
13594                    } else {
13595                        errorMsg = mContext.getResources().getText(
13596                                com.android.internal.R.string.factorytest_not_system);
13597                    }
13598                } else {
13599                    errorMsg = mContext.getResources().getText(
13600                            com.android.internal.R.string.factorytest_no_action);
13601                }
13602                if (errorMsg != null) {
13603                    mTopAction = null;
13604                    mTopData = null;
13605                    mTopComponent = null;
13606                    Message msg = Message.obtain();
13607                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13608                    msg.getData().putCharSequence("msg", errorMsg);
13609                    mUiHandler.sendMessage(msg);
13610                }
13611            }
13612        }
13613
13614        retrieveSettings();
13615        final int currentUserId;
13616        synchronized (this) {
13617            currentUserId = mUserController.getCurrentUserIdLocked();
13618            readGrantedUriPermissionsLocked();
13619        }
13620
13621        if (goingCallback != null) goingCallback.run();
13622        traceLog.traceBegin("ActivityManagerStartApps");
13623        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13624                Integer.toString(currentUserId), currentUserId);
13625        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13626                Integer.toString(currentUserId), currentUserId);
13627        mSystemServiceManager.startUser(currentUserId);
13628
13629        synchronized (this) {
13630            // Only start up encryption-aware persistent apps; once user is
13631            // unlocked we'll come back around and start unaware apps
13632            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13633
13634            // Start up initial activity.
13635            mBooting = true;
13636            // Enable home activity for system user, so that the system can always boot. We don't
13637            // do this when the system user is not setup since the setup wizard should be the one
13638            // to handle home activity in this case.
13639            if (UserManager.isSplitSystemUser() &&
13640                    Settings.Secure.getInt(mContext.getContentResolver(),
13641                         Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
13642                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13643                try {
13644                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13645                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13646                            UserHandle.USER_SYSTEM);
13647                } catch (RemoteException e) {
13648                    throw e.rethrowAsRuntimeException();
13649                }
13650            }
13651            startHomeActivityLocked(currentUserId, "systemReady");
13652
13653            try {
13654                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13655                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13656                            + " data partition or your device will be unstable.");
13657                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13658                }
13659            } catch (RemoteException e) {
13660            }
13661
13662            if (!Build.isBuildConsistent()) {
13663                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13664                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13665            }
13666
13667            long ident = Binder.clearCallingIdentity();
13668            try {
13669                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13670                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13671                        | Intent.FLAG_RECEIVER_FOREGROUND);
13672                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13673                broadcastIntentLocked(null, null, intent,
13674                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13675                        null, false, false, MY_PID, Process.SYSTEM_UID,
13676                        currentUserId);
13677                intent = new Intent(Intent.ACTION_USER_STARTING);
13678                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13679                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13680                broadcastIntentLocked(null, null, intent,
13681                        null, new IIntentReceiver.Stub() {
13682                            @Override
13683                            public void performReceive(Intent intent, int resultCode, String data,
13684                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13685                                    throws RemoteException {
13686                            }
13687                        }, 0, null, null,
13688                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13689                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13690            } catch (Throwable t) {
13691                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13692            } finally {
13693                Binder.restoreCallingIdentity(ident);
13694            }
13695            mStackSupervisor.resumeFocusedStackTopActivityLocked();
13696            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13697            traceLog.traceEnd(); // ActivityManagerStartApps
13698            traceLog.traceEnd(); // PhaseActivityManagerReady
13699        }
13700    }
13701
13702    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13703        synchronized (this) {
13704            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13705        }
13706    }
13707
13708    void skipCurrentReceiverLocked(ProcessRecord app) {
13709        for (BroadcastQueue queue : mBroadcastQueues) {
13710            queue.skipCurrentReceiverLocked(app);
13711        }
13712    }
13713
13714    /**
13715     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13716     * The application process will exit immediately after this call returns.
13717     * @param app object of the crashing app, null for the system server
13718     * @param crashInfo describing the exception
13719     */
13720    public void handleApplicationCrash(IBinder app,
13721            ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
13722        ProcessRecord r = findAppProcess(app, "Crash");
13723        final String processName = app == null ? "system_server"
13724                : (r == null ? "unknown" : r.processName);
13725
13726        handleApplicationCrashInner("crash", r, processName, crashInfo);
13727    }
13728
13729    /* Native crash reporting uses this inner version because it needs to be somewhat
13730     * decoupled from the AM-managed cleanup lifecycle
13731     */
13732    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13733            ApplicationErrorReport.CrashInfo crashInfo) {
13734        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13735                UserHandle.getUserId(Binder.getCallingUid()), processName,
13736                r == null ? -1 : r.info.flags,
13737                crashInfo.exceptionClassName,
13738                crashInfo.exceptionMessage,
13739                crashInfo.throwFileName,
13740                crashInfo.throwLineNumber);
13741
13742        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13743
13744        mAppErrors.crashApplication(r, crashInfo);
13745    }
13746
13747    public void handleApplicationStrictModeViolation(
13748            IBinder app,
13749            int violationMask,
13750            StrictMode.ViolationInfo info) {
13751        ProcessRecord r = findAppProcess(app, "StrictMode");
13752        if (r == null) {
13753            return;
13754        }
13755
13756        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13757            Integer stackFingerprint = info.hashCode();
13758            boolean logIt = true;
13759            synchronized (mAlreadyLoggedViolatedStacks) {
13760                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13761                    logIt = false;
13762                    // TODO: sub-sample into EventLog for these, with
13763                    // the info.durationMillis?  Then we'd get
13764                    // the relative pain numbers, without logging all
13765                    // the stack traces repeatedly.  We'd want to do
13766                    // likewise in the client code, which also does
13767                    // dup suppression, before the Binder call.
13768                } else {
13769                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13770                        mAlreadyLoggedViolatedStacks.clear();
13771                    }
13772                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13773                }
13774            }
13775            if (logIt) {
13776                logStrictModeViolationToDropBox(r, info);
13777            }
13778        }
13779
13780        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13781            AppErrorResult result = new AppErrorResult();
13782            synchronized (this) {
13783                final long origId = Binder.clearCallingIdentity();
13784
13785                Message msg = Message.obtain();
13786                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13787                HashMap<String, Object> data = new HashMap<String, Object>();
13788                data.put("result", result);
13789                data.put("app", r);
13790                data.put("violationMask", violationMask);
13791                data.put("info", info);
13792                msg.obj = data;
13793                mUiHandler.sendMessage(msg);
13794
13795                Binder.restoreCallingIdentity(origId);
13796            }
13797            int res = result.get();
13798            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13799        }
13800    }
13801
13802    // Depending on the policy in effect, there could be a bunch of
13803    // these in quick succession so we try to batch these together to
13804    // minimize disk writes, number of dropbox entries, and maximize
13805    // compression, by having more fewer, larger records.
13806    private void logStrictModeViolationToDropBox(
13807            ProcessRecord process,
13808            StrictMode.ViolationInfo info) {
13809        if (info == null) {
13810            return;
13811        }
13812        final boolean isSystemApp = process == null ||
13813                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13814                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13815        final String processName = process == null ? "unknown" : process.processName;
13816        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13817        final DropBoxManager dbox = (DropBoxManager)
13818                mContext.getSystemService(Context.DROPBOX_SERVICE);
13819
13820        // Exit early if the dropbox isn't configured to accept this report type.
13821        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13822
13823        boolean bufferWasEmpty;
13824        boolean needsFlush;
13825        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13826        synchronized (sb) {
13827            bufferWasEmpty = sb.length() == 0;
13828            appendDropBoxProcessHeaders(process, processName, sb);
13829            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13830            sb.append("System-App: ").append(isSystemApp).append("\n");
13831            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13832            if (info.violationNumThisLoop != 0) {
13833                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13834            }
13835            if (info.numAnimationsRunning != 0) {
13836                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13837            }
13838            if (info.broadcastIntentAction != null) {
13839                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13840            }
13841            if (info.durationMillis != -1) {
13842                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13843            }
13844            if (info.numInstances != -1) {
13845                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13846            }
13847            if (info.tags != null) {
13848                for (String tag : info.tags) {
13849                    sb.append("Span-Tag: ").append(tag).append("\n");
13850                }
13851            }
13852            sb.append("\n");
13853            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13854                sb.append(info.crashInfo.stackTrace);
13855                sb.append("\n");
13856            }
13857            if (info.message != null) {
13858                sb.append(info.message);
13859                sb.append("\n");
13860            }
13861
13862            // Only buffer up to ~64k.  Various logging bits truncate
13863            // things at 128k.
13864            needsFlush = (sb.length() > 64 * 1024);
13865        }
13866
13867        // Flush immediately if the buffer's grown too large, or this
13868        // is a non-system app.  Non-system apps are isolated with a
13869        // different tag & policy and not batched.
13870        //
13871        // Batching is useful during internal testing with
13872        // StrictMode settings turned up high.  Without batching,
13873        // thousands of separate files could be created on boot.
13874        if (!isSystemApp || needsFlush) {
13875            new Thread("Error dump: " + dropboxTag) {
13876                @Override
13877                public void run() {
13878                    String report;
13879                    synchronized (sb) {
13880                        report = sb.toString();
13881                        sb.delete(0, sb.length());
13882                        sb.trimToSize();
13883                    }
13884                    if (report.length() != 0) {
13885                        dbox.addText(dropboxTag, report);
13886                    }
13887                }
13888            }.start();
13889            return;
13890        }
13891
13892        // System app batching:
13893        if (!bufferWasEmpty) {
13894            // An existing dropbox-writing thread is outstanding, so
13895            // we don't need to start it up.  The existing thread will
13896            // catch the buffer appends we just did.
13897            return;
13898        }
13899
13900        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13901        // (After this point, we shouldn't access AMS internal data structures.)
13902        new Thread("Error dump: " + dropboxTag) {
13903            @Override
13904            public void run() {
13905                // 5 second sleep to let stacks arrive and be batched together
13906                try {
13907                    Thread.sleep(5000);  // 5 seconds
13908                } catch (InterruptedException e) {}
13909
13910                String errorReport;
13911                synchronized (mStrictModeBuffer) {
13912                    errorReport = mStrictModeBuffer.toString();
13913                    if (errorReport.length() == 0) {
13914                        return;
13915                    }
13916                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13917                    mStrictModeBuffer.trimToSize();
13918                }
13919                dbox.addText(dropboxTag, errorReport);
13920            }
13921        }.start();
13922    }
13923
13924    /**
13925     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13926     * @param app object of the crashing app, null for the system server
13927     * @param tag reported by the caller
13928     * @param system whether this wtf is coming from the system
13929     * @param crashInfo describing the context of the error
13930     * @return true if the process should exit immediately (WTF is fatal)
13931     */
13932    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13933            final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
13934        final int callingUid = Binder.getCallingUid();
13935        final int callingPid = Binder.getCallingPid();
13936
13937        if (system) {
13938            // If this is coming from the system, we could very well have low-level
13939            // system locks held, so we want to do this all asynchronously.  And we
13940            // never want this to become fatal, so there is that too.
13941            mHandler.post(new Runnable() {
13942                @Override public void run() {
13943                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13944                }
13945            });
13946            return false;
13947        }
13948
13949        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13950                crashInfo);
13951
13952        final boolean isFatal = "eng".equals(Build.TYPE) || Settings.Global
13953                .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
13954        final boolean isSystem = (r == null) || r.persistent;
13955
13956        if (isFatal && !isSystem) {
13957            mAppErrors.crashApplication(r, crashInfo);
13958            return true;
13959        } else {
13960            return false;
13961        }
13962    }
13963
13964    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13965            final ApplicationErrorReport.CrashInfo crashInfo) {
13966        final ProcessRecord r = findAppProcess(app, "WTF");
13967        final String processName = app == null ? "system_server"
13968                : (r == null ? "unknown" : r.processName);
13969
13970        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13971                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13972
13973        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13974
13975        return r;
13976    }
13977
13978    /**
13979     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13980     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13981     */
13982    private ProcessRecord findAppProcess(IBinder app, String reason) {
13983        if (app == null) {
13984            return null;
13985        }
13986
13987        synchronized (this) {
13988            final int NP = mProcessNames.getMap().size();
13989            for (int ip=0; ip<NP; ip++) {
13990                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13991                final int NA = apps.size();
13992                for (int ia=0; ia<NA; ia++) {
13993                    ProcessRecord p = apps.valueAt(ia);
13994                    if (p.thread != null && p.thread.asBinder() == app) {
13995                        return p;
13996                    }
13997                }
13998            }
13999
14000            Slog.w(TAG, "Can't find mystery application for " + reason
14001                    + " from pid=" + Binder.getCallingPid()
14002                    + " uid=" + Binder.getCallingUid() + ": " + app);
14003            return null;
14004        }
14005    }
14006
14007    /**
14008     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
14009     * to append various headers to the dropbox log text.
14010     */
14011    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
14012            StringBuilder sb) {
14013        // Watchdog thread ends up invoking this function (with
14014        // a null ProcessRecord) to add the stack file to dropbox.
14015        // Do not acquire a lock on this (am) in such cases, as it
14016        // could cause a potential deadlock, if and when watchdog
14017        // is invoked due to unavailability of lock on am and it
14018        // would prevent watchdog from killing system_server.
14019        if (process == null) {
14020            sb.append("Process: ").append(processName).append("\n");
14021            return;
14022        }
14023        // Note: ProcessRecord 'process' is guarded by the service
14024        // instance.  (notably process.pkgList, which could otherwise change
14025        // concurrently during execution of this method)
14026        synchronized (this) {
14027            sb.append("Process: ").append(processName).append("\n");
14028            int flags = process.info.flags;
14029            IPackageManager pm = AppGlobals.getPackageManager();
14030            sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
14031            for (int ip=0; ip<process.pkgList.size(); ip++) {
14032                String pkg = process.pkgList.keyAt(ip);
14033                sb.append("Package: ").append(pkg);
14034                try {
14035                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
14036                    if (pi != null) {
14037                        sb.append(" v").append(pi.versionCode);
14038                        if (pi.versionName != null) {
14039                            sb.append(" (").append(pi.versionName).append(")");
14040                        }
14041                    }
14042                } catch (RemoteException e) {
14043                    Slog.e(TAG, "Error getting package info: " + pkg, e);
14044                }
14045                sb.append("\n");
14046            }
14047        }
14048    }
14049
14050    private static String processClass(ProcessRecord process) {
14051        if (process == null || process.pid == MY_PID) {
14052            return "system_server";
14053        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
14054            return "system_app";
14055        } else {
14056            return "data_app";
14057        }
14058    }
14059
14060    private volatile long mWtfClusterStart;
14061    private volatile int mWtfClusterCount;
14062
14063    /**
14064     * Write a description of an error (crash, WTF, ANR) to the drop box.
14065     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
14066     * @param process which caused the error, null means the system server
14067     * @param activity which triggered the error, null if unknown
14068     * @param parent activity related to the error, null if unknown
14069     * @param subject line related to the error, null if absent
14070     * @param report in long form describing the error, null if absent
14071     * @param dataFile text file to include in the report, null if none
14072     * @param crashInfo giving an application stack trace, null if absent
14073     */
14074    public void addErrorToDropBox(String eventType,
14075            ProcessRecord process, String processName, ActivityRecord activity,
14076            ActivityRecord parent, String subject,
14077            final String report, final File dataFile,
14078            final ApplicationErrorReport.CrashInfo crashInfo) {
14079        // NOTE -- this must never acquire the ActivityManagerService lock,
14080        // otherwise the watchdog may be prevented from resetting the system.
14081
14082        // Bail early if not published yet
14083        if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
14084        final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
14085
14086        // Exit early if the dropbox isn't configured to accept this report type.
14087        final String dropboxTag = processClass(process) + "_" + eventType;
14088        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14089
14090        // Rate-limit how often we're willing to do the heavy lifting below to
14091        // collect and record logs; currently 5 logs per 10 second period.
14092        final long now = SystemClock.elapsedRealtime();
14093        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
14094            mWtfClusterStart = now;
14095            mWtfClusterCount = 1;
14096        } else {
14097            if (mWtfClusterCount++ >= 5) return;
14098        }
14099
14100        final StringBuilder sb = new StringBuilder(1024);
14101        appendDropBoxProcessHeaders(process, processName, sb);
14102        if (process != null) {
14103            sb.append("Foreground: ")
14104                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
14105                    .append("\n");
14106        }
14107        if (activity != null) {
14108            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
14109        }
14110        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
14111            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
14112        }
14113        if (parent != null && parent != activity) {
14114            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
14115        }
14116        if (subject != null) {
14117            sb.append("Subject: ").append(subject).append("\n");
14118        }
14119        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14120        if (Debug.isDebuggerConnected()) {
14121            sb.append("Debugger: Connected\n");
14122        }
14123        sb.append("\n");
14124
14125        // Do the rest in a worker thread to avoid blocking the caller on I/O
14126        // (After this point, we shouldn't access AMS internal data structures.)
14127        Thread worker = new Thread("Error dump: " + dropboxTag) {
14128            @Override
14129            public void run() {
14130                if (report != null) {
14131                    sb.append(report);
14132                }
14133
14134                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
14135                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
14136                int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
14137                        - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
14138
14139                if (dataFile != null && maxDataFileSize > 0) {
14140                    try {
14141                        sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
14142                                    "\n\n[[TRUNCATED]]"));
14143                    } catch (IOException e) {
14144                        Slog.e(TAG, "Error reading " + dataFile, e);
14145                    }
14146                }
14147                if (crashInfo != null && crashInfo.stackTrace != null) {
14148                    sb.append(crashInfo.stackTrace);
14149                }
14150
14151                if (lines > 0) {
14152                    sb.append("\n");
14153
14154                    // Merge several logcat streams, and take the last N lines
14155                    InputStreamReader input = null;
14156                    try {
14157                        java.lang.Process logcat = new ProcessBuilder(
14158                                "/system/bin/timeout", "-k", "15s", "10s",
14159                                "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
14160                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
14161                                        .redirectErrorStream(true).start();
14162
14163                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
14164                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
14165                        input = new InputStreamReader(logcat.getInputStream());
14166
14167                        int num;
14168                        char[] buf = new char[8192];
14169                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
14170                    } catch (IOException e) {
14171                        Slog.e(TAG, "Error running logcat", e);
14172                    } finally {
14173                        if (input != null) try { input.close(); } catch (IOException e) {}
14174                    }
14175                }
14176
14177                dbox.addText(dropboxTag, sb.toString());
14178            }
14179        };
14180
14181        if (process == null) {
14182            // If process is null, we are being called from some internal code
14183            // and may be about to die -- run this synchronously.
14184            worker.run();
14185        } else {
14186            worker.start();
14187        }
14188    }
14189
14190    @Override
14191    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
14192        enforceNotIsolatedCaller("getProcessesInErrorState");
14193        // assume our apps are happy - lazy create the list
14194        List<ActivityManager.ProcessErrorStateInfo> errList = null;
14195
14196        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14197                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
14198        int userId = UserHandle.getUserId(Binder.getCallingUid());
14199
14200        synchronized (this) {
14201
14202            // iterate across all processes
14203            for (int i=mLruProcesses.size()-1; i>=0; i--) {
14204                ProcessRecord app = mLruProcesses.get(i);
14205                if (!allUsers && app.userId != userId) {
14206                    continue;
14207                }
14208                if ((app.thread != null) && (app.crashing || app.notResponding)) {
14209                    // This one's in trouble, so we'll generate a report for it
14210                    // crashes are higher priority (in case there's a crash *and* an anr)
14211                    ActivityManager.ProcessErrorStateInfo report = null;
14212                    if (app.crashing) {
14213                        report = app.crashingReport;
14214                    } else if (app.notResponding) {
14215                        report = app.notRespondingReport;
14216                    }
14217
14218                    if (report != null) {
14219                        if (errList == null) {
14220                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
14221                        }
14222                        errList.add(report);
14223                    } else {
14224                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
14225                                " crashing = " + app.crashing +
14226                                " notResponding = " + app.notResponding);
14227                    }
14228                }
14229            }
14230        }
14231
14232        return errList;
14233    }
14234
14235    static int procStateToImportance(int procState, int memAdj,
14236            ActivityManager.RunningAppProcessInfo currApp) {
14237        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
14238        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
14239            currApp.lru = memAdj;
14240        } else {
14241            currApp.lru = 0;
14242        }
14243        return imp;
14244    }
14245
14246    private void fillInProcMemInfo(ProcessRecord app,
14247            ActivityManager.RunningAppProcessInfo outInfo) {
14248        outInfo.pid = app.pid;
14249        outInfo.uid = app.info.uid;
14250        if (mHeavyWeightProcess == app) {
14251            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
14252        }
14253        if (app.persistent) {
14254            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
14255        }
14256        if (app.activities.size() > 0) {
14257            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
14258        }
14259        outInfo.lastTrimLevel = app.trimMemoryLevel;
14260        int adj = app.curAdj;
14261        int procState = app.curProcState;
14262        outInfo.importance = procStateToImportance(procState, adj, outInfo);
14263        outInfo.importanceReasonCode = app.adjTypeCode;
14264        outInfo.processState = app.curProcState;
14265    }
14266
14267    @Override
14268    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
14269        enforceNotIsolatedCaller("getRunningAppProcesses");
14270
14271        final int callingUid = Binder.getCallingUid();
14272
14273        // Lazy instantiation of list
14274        List<ActivityManager.RunningAppProcessInfo> runList = null;
14275        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14276                callingUid) == PackageManager.PERMISSION_GRANTED;
14277        final int userId = UserHandle.getUserId(callingUid);
14278        final boolean allUids = isGetTasksAllowed(
14279                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
14280
14281        synchronized (this) {
14282            // Iterate across all processes
14283            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14284                ProcessRecord app = mLruProcesses.get(i);
14285                if ((!allUsers && app.userId != userId)
14286                        || (!allUids && app.uid != callingUid)) {
14287                    continue;
14288                }
14289                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
14290                    // Generate process state info for running application
14291                    ActivityManager.RunningAppProcessInfo currApp =
14292                        new ActivityManager.RunningAppProcessInfo(app.processName,
14293                                app.pid, app.getPackageList());
14294                    fillInProcMemInfo(app, currApp);
14295                    if (app.adjSource instanceof ProcessRecord) {
14296                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
14297                        currApp.importanceReasonImportance =
14298                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
14299                                        app.adjSourceProcState);
14300                    } else if (app.adjSource instanceof ActivityRecord) {
14301                        ActivityRecord r = (ActivityRecord)app.adjSource;
14302                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
14303                    }
14304                    if (app.adjTarget instanceof ComponentName) {
14305                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
14306                    }
14307                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
14308                    //        + " lru=" + currApp.lru);
14309                    if (runList == null) {
14310                        runList = new ArrayList<>();
14311                    }
14312                    runList.add(currApp);
14313                }
14314            }
14315        }
14316        return runList;
14317    }
14318
14319    @Override
14320    public List<ApplicationInfo> getRunningExternalApplications() {
14321        enforceNotIsolatedCaller("getRunningExternalApplications");
14322        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14323        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14324        if (runningApps != null && runningApps.size() > 0) {
14325            Set<String> extList = new HashSet<String>();
14326            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14327                if (app.pkgList != null) {
14328                    for (String pkg : app.pkgList) {
14329                        extList.add(pkg);
14330                    }
14331                }
14332            }
14333            IPackageManager pm = AppGlobals.getPackageManager();
14334            for (String pkg : extList) {
14335                try {
14336                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14337                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14338                        retList.add(info);
14339                    }
14340                } catch (RemoteException e) {
14341                }
14342            }
14343        }
14344        return retList;
14345    }
14346
14347    @Override
14348    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
14349        enforceNotIsolatedCaller("getMyMemoryState");
14350        synchronized (this) {
14351            ProcessRecord proc;
14352            synchronized (mPidsSelfLocked) {
14353                proc = mPidsSelfLocked.get(Binder.getCallingPid());
14354            }
14355            fillInProcMemInfo(proc, outInfo);
14356        }
14357    }
14358
14359    @Override
14360    public int getMemoryTrimLevel() {
14361        enforceNotIsolatedCaller("getMyMemoryState");
14362        synchronized (this) {
14363            return mLastMemoryLevel;
14364        }
14365    }
14366
14367    @Override
14368    public void onShellCommand(FileDescriptor in, FileDescriptor out,
14369            FileDescriptor err, String[] args, ShellCallback callback,
14370            ResultReceiver resultReceiver) {
14371        (new ActivityManagerShellCommand(this, false)).exec(
14372                this, in, out, err, args, callback, resultReceiver);
14373    }
14374
14375    @Override
14376    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
14377        if (checkCallingPermission(android.Manifest.permission.DUMP)
14378                != PackageManager.PERMISSION_GRANTED) {
14379            pw.println("Permission Denial: can't dump ActivityManager from from pid="
14380                    + Binder.getCallingPid()
14381                    + ", uid=" + Binder.getCallingUid()
14382                    + " without permission "
14383                    + android.Manifest.permission.DUMP);
14384            return;
14385        }
14386
14387        boolean dumpAll = false;
14388        boolean dumpClient = false;
14389        boolean dumpCheckin = false;
14390        boolean dumpCheckinFormat = false;
14391        boolean dumpVisibleStacks = false;
14392        String dumpPackage = null;
14393
14394        int opti = 0;
14395        while (opti < args.length) {
14396            String opt = args[opti];
14397            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14398                break;
14399            }
14400            opti++;
14401            if ("-a".equals(opt)) {
14402                dumpAll = true;
14403            } else if ("-c".equals(opt)) {
14404                dumpClient = true;
14405            } else if ("-v".equals(opt)) {
14406                dumpVisibleStacks = true;
14407            } else if ("-p".equals(opt)) {
14408                if (opti < args.length) {
14409                    dumpPackage = args[opti];
14410                    opti++;
14411                } else {
14412                    pw.println("Error: -p option requires package argument");
14413                    return;
14414                }
14415                dumpClient = true;
14416            } else if ("--checkin".equals(opt)) {
14417                dumpCheckin = dumpCheckinFormat = true;
14418            } else if ("-C".equals(opt)) {
14419                dumpCheckinFormat = true;
14420            } else if ("-h".equals(opt)) {
14421                ActivityManagerShellCommand.dumpHelp(pw, true);
14422                return;
14423            } else {
14424                pw.println("Unknown argument: " + opt + "; use -h for help");
14425            }
14426        }
14427
14428        long origId = Binder.clearCallingIdentity();
14429        boolean more = false;
14430        // Is the caller requesting to dump a particular piece of data?
14431        if (opti < args.length) {
14432            String cmd = args[opti];
14433            opti++;
14434            if ("activities".equals(cmd) || "a".equals(cmd)) {
14435                synchronized (this) {
14436                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14437                }
14438            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
14439                synchronized (this) {
14440                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
14441                }
14442            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
14443                String[] newArgs;
14444                String name;
14445                if (opti >= args.length) {
14446                    name = null;
14447                    newArgs = EMPTY_STRING_ARRAY;
14448                } else {
14449                    dumpPackage = args[opti];
14450                    opti++;
14451                    newArgs = new String[args.length - opti];
14452                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14453                            args.length - opti);
14454                }
14455                synchronized (this) {
14456                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
14457                }
14458            } else if ("broadcast-stats".equals(cmd)) {
14459                String[] newArgs;
14460                String name;
14461                if (opti >= args.length) {
14462                    name = null;
14463                    newArgs = EMPTY_STRING_ARRAY;
14464                } else {
14465                    dumpPackage = args[opti];
14466                    opti++;
14467                    newArgs = new String[args.length - opti];
14468                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14469                            args.length - opti);
14470                }
14471                synchronized (this) {
14472                    if (dumpCheckinFormat) {
14473                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
14474                                dumpPackage);
14475                    } else {
14476                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
14477                    }
14478                }
14479            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
14480                String[] newArgs;
14481                String name;
14482                if (opti >= args.length) {
14483                    name = null;
14484                    newArgs = EMPTY_STRING_ARRAY;
14485                } else {
14486                    dumpPackage = args[opti];
14487                    opti++;
14488                    newArgs = new String[args.length - opti];
14489                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14490                            args.length - opti);
14491                }
14492                synchronized (this) {
14493                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
14494                }
14495            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
14496                String[] newArgs;
14497                String name;
14498                if (opti >= args.length) {
14499                    name = null;
14500                    newArgs = EMPTY_STRING_ARRAY;
14501                } else {
14502                    dumpPackage = args[opti];
14503                    opti++;
14504                    newArgs = new String[args.length - opti];
14505                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14506                            args.length - opti);
14507                }
14508                synchronized (this) {
14509                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
14510                }
14511            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
14512                synchronized (this) {
14513                    dumpOomLocked(fd, pw, args, opti, true);
14514                }
14515            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
14516                synchronized (this) {
14517                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
14518                }
14519            } else if ("provider".equals(cmd)) {
14520                String[] newArgs;
14521                String name;
14522                if (opti >= args.length) {
14523                    name = null;
14524                    newArgs = EMPTY_STRING_ARRAY;
14525                } else {
14526                    name = args[opti];
14527                    opti++;
14528                    newArgs = new String[args.length - opti];
14529                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14530                }
14531                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
14532                    pw.println("No providers match: " + name);
14533                    pw.println("Use -h for help.");
14534                }
14535            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
14536                synchronized (this) {
14537                    dumpProvidersLocked(fd, pw, args, opti, true, null);
14538                }
14539            } else if ("service".equals(cmd)) {
14540                String[] newArgs;
14541                String name;
14542                if (opti >= args.length) {
14543                    name = null;
14544                    newArgs = EMPTY_STRING_ARRAY;
14545                } else {
14546                    name = args[opti];
14547                    opti++;
14548                    newArgs = new String[args.length - opti];
14549                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14550                            args.length - opti);
14551                }
14552                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14553                    pw.println("No services match: " + name);
14554                    pw.println("Use -h for help.");
14555                }
14556            } else if ("package".equals(cmd)) {
14557                String[] newArgs;
14558                if (opti >= args.length) {
14559                    pw.println("package: no package name specified");
14560                    pw.println("Use -h for help.");
14561                } else {
14562                    dumpPackage = args[opti];
14563                    opti++;
14564                    newArgs = new String[args.length - opti];
14565                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14566                            args.length - opti);
14567                    args = newArgs;
14568                    opti = 0;
14569                    more = true;
14570                }
14571            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14572                synchronized (this) {
14573                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14574                }
14575            } else if ("settings".equals(cmd)) {
14576                synchronized (this) {
14577                    mConstants.dump(pw);
14578                }
14579            } else if ("services".equals(cmd) || "s".equals(cmd)) {
14580                if (dumpClient) {
14581                    ActiveServices.ServiceDumper dumper;
14582                    synchronized (this) {
14583                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14584                                dumpPackage);
14585                    }
14586                    dumper.dumpWithClient();
14587                } else {
14588                    synchronized (this) {
14589                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14590                                dumpPackage).dumpLocked();
14591                    }
14592                }
14593            } else if ("locks".equals(cmd)) {
14594                LockGuard.dump(fd, pw, args);
14595            } else {
14596                // Dumping a single activity?
14597                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacks)) {
14598                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14599                    int res = shell.exec(this, null, fd, null, args, null,
14600                            new ResultReceiver(null));
14601                    if (res < 0) {
14602                        pw.println("Bad activity command, or no activities match: " + cmd);
14603                        pw.println("Use -h for help.");
14604                    }
14605                }
14606            }
14607            if (!more) {
14608                Binder.restoreCallingIdentity(origId);
14609                return;
14610            }
14611        }
14612
14613        // No piece of data specified, dump everything.
14614        if (dumpCheckinFormat) {
14615            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14616        } else if (dumpClient) {
14617            ActiveServices.ServiceDumper sdumper;
14618            synchronized (this) {
14619                mConstants.dump(pw);
14620                pw.println();
14621                if (dumpAll) {
14622                    pw.println("-------------------------------------------------------------------------------");
14623                }
14624                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14625                pw.println();
14626                if (dumpAll) {
14627                    pw.println("-------------------------------------------------------------------------------");
14628                }
14629                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14630                pw.println();
14631                if (dumpAll) {
14632                    pw.println("-------------------------------------------------------------------------------");
14633                }
14634                if (dumpAll || dumpPackage != null) {
14635                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14636                    pw.println();
14637                    if (dumpAll) {
14638                        pw.println("-------------------------------------------------------------------------------");
14639                    }
14640                }
14641                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14642                pw.println();
14643                if (dumpAll) {
14644                    pw.println("-------------------------------------------------------------------------------");
14645                }
14646                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14647                pw.println();
14648                if (dumpAll) {
14649                    pw.println("-------------------------------------------------------------------------------");
14650                }
14651                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14652                        dumpPackage);
14653            }
14654            sdumper.dumpWithClient();
14655            pw.println();
14656            synchronized (this) {
14657                if (dumpAll) {
14658                    pw.println("-------------------------------------------------------------------------------");
14659                }
14660                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14661                pw.println();
14662                if (dumpAll) {
14663                    pw.println("-------------------------------------------------------------------------------");
14664                }
14665                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14666                if (mAssociations.size() > 0) {
14667                    pw.println();
14668                    if (dumpAll) {
14669                        pw.println("-------------------------------------------------------------------------------");
14670                    }
14671                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14672                }
14673                pw.println();
14674                if (dumpAll) {
14675                    pw.println("-------------------------------------------------------------------------------");
14676                }
14677                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14678            }
14679
14680        } else {
14681            synchronized (this) {
14682                mConstants.dump(pw);
14683                pw.println();
14684                if (dumpAll) {
14685                    pw.println("-------------------------------------------------------------------------------");
14686                }
14687                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14688                pw.println();
14689                if (dumpAll) {
14690                    pw.println("-------------------------------------------------------------------------------");
14691                }
14692                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14693                pw.println();
14694                if (dumpAll) {
14695                    pw.println("-------------------------------------------------------------------------------");
14696                }
14697                if (dumpAll || dumpPackage != null) {
14698                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14699                    pw.println();
14700                    if (dumpAll) {
14701                        pw.println("-------------------------------------------------------------------------------");
14702                    }
14703                }
14704                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14705                pw.println();
14706                if (dumpAll) {
14707                    pw.println("-------------------------------------------------------------------------------");
14708                }
14709                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14710                pw.println();
14711                if (dumpAll) {
14712                    pw.println("-------------------------------------------------------------------------------");
14713                }
14714                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14715                        .dumpLocked();
14716                pw.println();
14717                if (dumpAll) {
14718                    pw.println("-------------------------------------------------------------------------------");
14719                }
14720                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14721                pw.println();
14722                if (dumpAll) {
14723                    pw.println("-------------------------------------------------------------------------------");
14724                }
14725                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14726                if (mAssociations.size() > 0) {
14727                    pw.println();
14728                    if (dumpAll) {
14729                        pw.println("-------------------------------------------------------------------------------");
14730                    }
14731                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14732                }
14733                pw.println();
14734                if (dumpAll) {
14735                    pw.println("-------------------------------------------------------------------------------");
14736                }
14737                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14738            }
14739        }
14740        Binder.restoreCallingIdentity(origId);
14741    }
14742
14743    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14744            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14745        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14746
14747        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14748                dumpPackage);
14749        boolean needSep = printedAnything;
14750
14751        boolean printed = ActivityStackSupervisor.printThisActivity(pw,
14752                mStackSupervisor.getResumedActivityLocked(),
14753                dumpPackage, needSep, "  ResumedActivity: ");
14754        if (printed) {
14755            printedAnything = true;
14756            needSep = false;
14757        }
14758
14759        if (dumpPackage == null) {
14760            if (needSep) {
14761                pw.println();
14762            }
14763            needSep = true;
14764            printedAnything = true;
14765            mStackSupervisor.dump(pw, "  ");
14766        }
14767
14768        if (!printedAnything) {
14769            pw.println("  (nothing)");
14770        }
14771    }
14772
14773    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14774            int opti, boolean dumpAll, String dumpPackage) {
14775        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14776
14777        boolean printedAnything = false;
14778
14779        if (mRecentTasks != null && mRecentTasks.size() > 0) {
14780            boolean printedHeader = false;
14781
14782            final int N = mRecentTasks.size();
14783            for (int i=0; i<N; i++) {
14784                TaskRecord tr = mRecentTasks.get(i);
14785                if (dumpPackage != null) {
14786                    if (tr.realActivity == null ||
14787                            !dumpPackage.equals(tr.realActivity.getPackageName())) {
14788                        continue;
14789                    }
14790                }
14791                if (!printedHeader) {
14792                    pw.println("  Recent tasks:");
14793                    printedHeader = true;
14794                    printedAnything = true;
14795                }
14796                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14797                        pw.println(tr);
14798                if (dumpAll) {
14799                    mRecentTasks.get(i).dump(pw, "    ");
14800                }
14801            }
14802        }
14803
14804        if (!printedAnything) {
14805            pw.println("  (nothing)");
14806        }
14807    }
14808
14809    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14810            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14811        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14812
14813        int dumpUid = 0;
14814        if (dumpPackage != null) {
14815            IPackageManager pm = AppGlobals.getPackageManager();
14816            try {
14817                dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
14818            } catch (RemoteException e) {
14819            }
14820        }
14821
14822        boolean printedAnything = false;
14823
14824        final long now = SystemClock.uptimeMillis();
14825
14826        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14827            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14828                    = mAssociations.valueAt(i1);
14829            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14830                SparseArray<ArrayMap<String, Association>> sourceUids
14831                        = targetComponents.valueAt(i2);
14832                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14833                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14834                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14835                        Association ass = sourceProcesses.valueAt(i4);
14836                        if (dumpPackage != null) {
14837                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14838                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14839                                continue;
14840                            }
14841                        }
14842                        printedAnything = true;
14843                        pw.print("  ");
14844                        pw.print(ass.mTargetProcess);
14845                        pw.print("/");
14846                        UserHandle.formatUid(pw, ass.mTargetUid);
14847                        pw.print(" <- ");
14848                        pw.print(ass.mSourceProcess);
14849                        pw.print("/");
14850                        UserHandle.formatUid(pw, ass.mSourceUid);
14851                        pw.println();
14852                        pw.print("    via ");
14853                        pw.print(ass.mTargetComponent.flattenToShortString());
14854                        pw.println();
14855                        pw.print("    ");
14856                        long dur = ass.mTime;
14857                        if (ass.mNesting > 0) {
14858                            dur += now - ass.mStartTime;
14859                        }
14860                        TimeUtils.formatDuration(dur, pw);
14861                        pw.print(" (");
14862                        pw.print(ass.mCount);
14863                        pw.print(" times)");
14864                        pw.print("  ");
14865                        for (int i=0; i<ass.mStateTimes.length; i++) {
14866                            long amt = ass.mStateTimes[i];
14867                            if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
14868                                amt += now - ass.mLastStateUptime;
14869                            }
14870                            if (amt != 0) {
14871                                pw.print(" ");
14872                                pw.print(ProcessList.makeProcStateString(
14873                                            i + ActivityManager.MIN_PROCESS_STATE));
14874                                pw.print("=");
14875                                TimeUtils.formatDuration(amt, pw);
14876                                if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
14877                                    pw.print("*");
14878                                }
14879                            }
14880                        }
14881                        pw.println();
14882                        if (ass.mNesting > 0) {
14883                            pw.print("    Currently active: ");
14884                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14885                            pw.println();
14886                        }
14887                    }
14888                }
14889            }
14890
14891        }
14892
14893        if (!printedAnything) {
14894            pw.println("  (nothing)");
14895        }
14896    }
14897
14898    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14899            String header, boolean needSep) {
14900        boolean printed = false;
14901        int whichAppId = -1;
14902        if (dumpPackage != null) {
14903            try {
14904                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14905                        dumpPackage, 0);
14906                whichAppId = UserHandle.getAppId(info.uid);
14907            } catch (NameNotFoundException e) {
14908                e.printStackTrace();
14909            }
14910        }
14911        for (int i=0; i<uids.size(); i++) {
14912            UidRecord uidRec = uids.valueAt(i);
14913            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14914                continue;
14915            }
14916            if (!printed) {
14917                printed = true;
14918                if (needSep) {
14919                    pw.println();
14920                }
14921                pw.print("  ");
14922                pw.println(header);
14923                needSep = true;
14924            }
14925            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14926            pw.print(": "); pw.println(uidRec);
14927        }
14928        return printed;
14929    }
14930
14931    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14932            int opti, boolean dumpAll, String dumpPackage) {
14933        boolean needSep = false;
14934        boolean printedAnything = false;
14935        int numPers = 0;
14936
14937        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14938
14939        if (dumpAll) {
14940            final int NP = mProcessNames.getMap().size();
14941            for (int ip=0; ip<NP; ip++) {
14942                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14943                final int NA = procs.size();
14944                for (int ia=0; ia<NA; ia++) {
14945                    ProcessRecord r = procs.valueAt(ia);
14946                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14947                        continue;
14948                    }
14949                    if (!needSep) {
14950                        pw.println("  All known processes:");
14951                        needSep = true;
14952                        printedAnything = true;
14953                    }
14954                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14955                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14956                        pw.print(" "); pw.println(r);
14957                    r.dump(pw, "    ");
14958                    if (r.persistent) {
14959                        numPers++;
14960                    }
14961                }
14962            }
14963        }
14964
14965        if (mIsolatedProcesses.size() > 0) {
14966            boolean printed = false;
14967            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14968                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14969                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14970                    continue;
14971                }
14972                if (!printed) {
14973                    if (needSep) {
14974                        pw.println();
14975                    }
14976                    pw.println("  Isolated process list (sorted by uid):");
14977                    printedAnything = true;
14978                    printed = true;
14979                    needSep = true;
14980                }
14981                pw.print("    Isolated #"); pw.print(i); pw.print(": ");
14982                pw.println(r);
14983            }
14984        }
14985
14986        if (mActiveInstrumentation.size() > 0) {
14987            boolean printed = false;
14988            for (int i=0; i<mActiveInstrumentation.size(); i++) {
14989                ActiveInstrumentation ai = mActiveInstrumentation.get(i);
14990                if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
14991                        && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
14992                    continue;
14993                }
14994                if (!printed) {
14995                    if (needSep) {
14996                        pw.println();
14997                    }
14998                    pw.println("  Active instrumentation:");
14999                    printedAnything = true;
15000                    printed = true;
15001                    needSep = true;
15002                }
15003                pw.print("    Instrumentation #"); pw.print(i); pw.print(": ");
15004                pw.println(ai);
15005                ai.dump(pw, "      ");
15006            }
15007        }
15008
15009        if (mActiveUids.size() > 0) {
15010            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
15011                printedAnything = needSep = true;
15012            }
15013        }
15014        if (mValidateUids.size() > 0) {
15015            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
15016                printedAnything = needSep = true;
15017            }
15018        }
15019
15020        if (mLruProcesses.size() > 0) {
15021            if (needSep) {
15022                pw.println();
15023            }
15024            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
15025                    pw.print(" total, non-act at ");
15026                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15027                    pw.print(", non-svc at ");
15028                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15029                    pw.println("):");
15030            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
15031            needSep = true;
15032            printedAnything = true;
15033        }
15034
15035        if (dumpAll || dumpPackage != null) {
15036            synchronized (mPidsSelfLocked) {
15037                boolean printed = false;
15038                for (int i=0; i<mPidsSelfLocked.size(); i++) {
15039                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
15040                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15041                        continue;
15042                    }
15043                    if (!printed) {
15044                        if (needSep) pw.println();
15045                        needSep = true;
15046                        pw.println("  PID mappings:");
15047                        printed = true;
15048                        printedAnything = true;
15049                    }
15050                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
15051                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
15052                }
15053            }
15054        }
15055
15056        if (mForegroundProcesses.size() > 0) {
15057            synchronized (mPidsSelfLocked) {
15058                boolean printed = false;
15059                for (int i=0; i<mForegroundProcesses.size(); i++) {
15060                    ProcessRecord r = mPidsSelfLocked.get(
15061                            mForegroundProcesses.valueAt(i).pid);
15062                    if (dumpPackage != null && (r == null
15063                            || !r.pkgList.containsKey(dumpPackage))) {
15064                        continue;
15065                    }
15066                    if (!printed) {
15067                        if (needSep) pw.println();
15068                        needSep = true;
15069                        pw.println("  Foreground Processes:");
15070                        printed = true;
15071                        printedAnything = true;
15072                    }
15073                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
15074                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
15075                }
15076            }
15077        }
15078
15079        if (mPersistentStartingProcesses.size() > 0) {
15080            if (needSep) pw.println();
15081            needSep = true;
15082            printedAnything = true;
15083            pw.println("  Persisent processes that are starting:");
15084            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
15085                    "Starting Norm", "Restarting PERS", dumpPackage);
15086        }
15087
15088        if (mRemovedProcesses.size() > 0) {
15089            if (needSep) pw.println();
15090            needSep = true;
15091            printedAnything = true;
15092            pw.println("  Processes that are being removed:");
15093            dumpProcessList(pw, this, mRemovedProcesses, "    ",
15094                    "Removed Norm", "Removed PERS", dumpPackage);
15095        }
15096
15097        if (mProcessesOnHold.size() > 0) {
15098            if (needSep) pw.println();
15099            needSep = true;
15100            printedAnything = true;
15101            pw.println("  Processes that are on old until the system is ready:");
15102            dumpProcessList(pw, this, mProcessesOnHold, "    ",
15103                    "OnHold Norm", "OnHold PERS", dumpPackage);
15104        }
15105
15106        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
15107
15108        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
15109        if (needSep) {
15110            printedAnything = true;
15111        }
15112
15113        if (dumpPackage == null) {
15114            pw.println();
15115            needSep = false;
15116            mUserController.dump(pw, dumpAll);
15117        }
15118        if (mHomeProcess != null && (dumpPackage == null
15119                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
15120            if (needSep) {
15121                pw.println();
15122                needSep = false;
15123            }
15124            pw.println("  mHomeProcess: " + mHomeProcess);
15125        }
15126        if (mPreviousProcess != null && (dumpPackage == null
15127                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
15128            if (needSep) {
15129                pw.println();
15130                needSep = false;
15131            }
15132            pw.println("  mPreviousProcess: " + mPreviousProcess);
15133        }
15134        if (dumpAll) {
15135            StringBuilder sb = new StringBuilder(128);
15136            sb.append("  mPreviousProcessVisibleTime: ");
15137            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
15138            pw.println(sb);
15139        }
15140        if (mHeavyWeightProcess != null && (dumpPackage == null
15141                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
15142            if (needSep) {
15143                pw.println();
15144                needSep = false;
15145            }
15146            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
15147        }
15148        if (dumpPackage == null) {
15149            pw.println("  mGlobalConfiguration: " + getGlobalConfiguration());
15150            mStackSupervisor.dumpDisplayConfigs(pw, "  ");
15151        }
15152        if (dumpAll) {
15153            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
15154            if (mCompatModePackages.getPackages().size() > 0) {
15155                boolean printed = false;
15156                for (Map.Entry<String, Integer> entry
15157                        : mCompatModePackages.getPackages().entrySet()) {
15158                    String pkg = entry.getKey();
15159                    int mode = entry.getValue();
15160                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
15161                        continue;
15162                    }
15163                    if (!printed) {
15164                        pw.println("  mScreenCompatPackages:");
15165                        printed = true;
15166                    }
15167                    pw.print("    "); pw.print(pkg); pw.print(": ");
15168                            pw.print(mode); pw.println();
15169                }
15170            }
15171            final int NI = mUidObservers.getRegisteredCallbackCount();
15172            boolean printed = false;
15173            for (int i=0; i<NI; i++) {
15174                final UidObserverRegistration reg = (UidObserverRegistration)
15175                        mUidObservers.getRegisteredCallbackCookie(i);
15176                if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
15177                    if (!printed) {
15178                        pw.println("  mUidObservers:");
15179                        printed = true;
15180                    }
15181                    pw.print("    "); UserHandle.formatUid(pw, reg.uid);
15182                    pw.print(" "); pw.print(reg.pkg); pw.print(":");
15183                    if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
15184                        pw.print(" IDLE");
15185                    }
15186                    if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
15187                        pw.print(" ACT" );
15188                    }
15189                    if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
15190                        pw.print(" GONE");
15191                    }
15192                    if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
15193                        pw.print(" STATE");
15194                        pw.print(" (cut="); pw.print(reg.cutpoint);
15195                        pw.print(")");
15196                    }
15197                    pw.println();
15198                    if (reg.lastProcStates != null) {
15199                        final int NJ = reg.lastProcStates.size();
15200                        for (int j=0; j<NJ; j++) {
15201                            pw.print("      Last ");
15202                            UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
15203                            pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
15204                        }
15205                    }
15206                }
15207            }
15208            pw.println("  mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
15209            pw.println("  mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
15210        }
15211        if (dumpPackage == null) {
15212            pw.println("  mWakefulness="
15213                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
15214            pw.println("  mSleepTokens=" + mSleepTokens);
15215            pw.println("  mSleeping=" + mSleeping);
15216            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
15217            if (mRunningVoice != null) {
15218                pw.println("  mRunningVoice=" + mRunningVoice);
15219                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
15220            }
15221        }
15222        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
15223                || mOrigWaitForDebugger) {
15224            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
15225                    || dumpPackage.equals(mOrigDebugApp)) {
15226                if (needSep) {
15227                    pw.println();
15228                    needSep = false;
15229                }
15230                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
15231                        + " mDebugTransient=" + mDebugTransient
15232                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
15233            }
15234        }
15235        if (mCurAppTimeTracker != null) {
15236            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
15237        }
15238        if (mMemWatchProcesses.getMap().size() > 0) {
15239            pw.println("  Mem watch processes:");
15240            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
15241                    = mMemWatchProcesses.getMap();
15242            for (int i=0; i<procs.size(); i++) {
15243                final String proc = procs.keyAt(i);
15244                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
15245                for (int j=0; j<uids.size(); j++) {
15246                    if (needSep) {
15247                        pw.println();
15248                        needSep = false;
15249                    }
15250                    StringBuilder sb = new StringBuilder();
15251                    sb.append("    ").append(proc).append('/');
15252                    UserHandle.formatUid(sb, uids.keyAt(j));
15253                    Pair<Long, String> val = uids.valueAt(j);
15254                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
15255                    if (val.second != null) {
15256                        sb.append(", report to ").append(val.second);
15257                    }
15258                    pw.println(sb.toString());
15259                }
15260            }
15261            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
15262            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
15263            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
15264                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
15265        }
15266        if (mTrackAllocationApp != null) {
15267            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
15268                if (needSep) {
15269                    pw.println();
15270                    needSep = false;
15271                }
15272                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
15273            }
15274        }
15275        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
15276                || mProfileFd != null) {
15277            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
15278                if (needSep) {
15279                    pw.println();
15280                    needSep = false;
15281                }
15282                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
15283                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
15284                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
15285                        + mAutoStopProfiler + " mStreamingOutput=" + mStreamingOutput);
15286                pw.println("  mProfileType=" + mProfileType);
15287            }
15288        }
15289        if (mNativeDebuggingApp != null) {
15290            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
15291                if (needSep) {
15292                    pw.println();
15293                    needSep = false;
15294                }
15295                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
15296            }
15297        }
15298        if (dumpPackage == null) {
15299            if (mAlwaysFinishActivities) {
15300                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities);
15301            }
15302            if (mController != null) {
15303                pw.println("  mController=" + mController
15304                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
15305            }
15306            if (dumpAll) {
15307                pw.println("  Total persistent processes: " + numPers);
15308                pw.println("  mProcessesReady=" + mProcessesReady
15309                        + " mSystemReady=" + mSystemReady
15310                        + " mBooted=" + mBooted
15311                        + " mFactoryTest=" + mFactoryTest);
15312                pw.println("  mBooting=" + mBooting
15313                        + " mCallFinishBooting=" + mCallFinishBooting
15314                        + " mBootAnimationComplete=" + mBootAnimationComplete);
15315                pw.print("  mLastPowerCheckRealtime=");
15316                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
15317                        pw.println("");
15318                pw.print("  mLastPowerCheckUptime=");
15319                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
15320                        pw.println("");
15321                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
15322                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
15323                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
15324                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
15325                        + " (" + mLruProcesses.size() + " total)"
15326                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
15327                        + " mNumServiceProcs=" + mNumServiceProcs
15328                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
15329                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
15330                        + " mLastMemoryLevel=" + mLastMemoryLevel
15331                        + " mLastNumProcesses=" + mLastNumProcesses);
15332                long now = SystemClock.uptimeMillis();
15333                pw.print("  mLastIdleTime=");
15334                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
15335                        pw.print(" mLowRamSinceLastIdle=");
15336                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
15337                        pw.println();
15338            }
15339        }
15340
15341        if (!printedAnything) {
15342            pw.println("  (nothing)");
15343        }
15344    }
15345
15346    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
15347            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
15348        if (mProcessesToGc.size() > 0) {
15349            boolean printed = false;
15350            long now = SystemClock.uptimeMillis();
15351            for (int i=0; i<mProcessesToGc.size(); i++) {
15352                ProcessRecord proc = mProcessesToGc.get(i);
15353                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
15354                    continue;
15355                }
15356                if (!printed) {
15357                    if (needSep) pw.println();
15358                    needSep = true;
15359                    pw.println("  Processes that are waiting to GC:");
15360                    printed = true;
15361                }
15362                pw.print("    Process "); pw.println(proc);
15363                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
15364                        pw.print(", last gced=");
15365                        pw.print(now-proc.lastRequestedGc);
15366                        pw.print(" ms ago, last lowMem=");
15367                        pw.print(now-proc.lastLowMemory);
15368                        pw.println(" ms ago");
15369
15370            }
15371        }
15372        return needSep;
15373    }
15374
15375    void printOomLevel(PrintWriter pw, String name, int adj) {
15376        pw.print("    ");
15377        if (adj >= 0) {
15378            pw.print(' ');
15379            if (adj < 10) pw.print(' ');
15380        } else {
15381            if (adj > -10) pw.print(' ');
15382        }
15383        pw.print(adj);
15384        pw.print(": ");
15385        pw.print(name);
15386        pw.print(" (");
15387        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
15388        pw.println(")");
15389    }
15390
15391    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15392            int opti, boolean dumpAll) {
15393        boolean needSep = false;
15394
15395        if (mLruProcesses.size() > 0) {
15396            if (needSep) pw.println();
15397            needSep = true;
15398            pw.println("  OOM levels:");
15399            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
15400            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
15401            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
15402            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
15403            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
15404            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
15405            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
15406            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
15407            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
15408            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
15409            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
15410            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
15411            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
15412            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
15413
15414            if (needSep) pw.println();
15415            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
15416                    pw.print(" total, non-act at ");
15417                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15418                    pw.print(", non-svc at ");
15419                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15420                    pw.println("):");
15421            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
15422            needSep = true;
15423        }
15424
15425        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
15426
15427        pw.println();
15428        pw.println("  mHomeProcess: " + mHomeProcess);
15429        pw.println("  mPreviousProcess: " + mPreviousProcess);
15430        if (mHeavyWeightProcess != null) {
15431            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
15432        }
15433
15434        return true;
15435    }
15436
15437    /**
15438     * There are three ways to call this:
15439     *  - no provider specified: dump all the providers
15440     *  - a flattened component name that matched an existing provider was specified as the
15441     *    first arg: dump that one provider
15442     *  - the first arg isn't the flattened component name of an existing provider:
15443     *    dump all providers whose component contains the first arg as a substring
15444     */
15445    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15446            int opti, boolean dumpAll) {
15447        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
15448    }
15449
15450    static class ItemMatcher {
15451        ArrayList<ComponentName> components;
15452        ArrayList<String> strings;
15453        ArrayList<Integer> objects;
15454        boolean all;
15455
15456        ItemMatcher() {
15457            all = true;
15458        }
15459
15460        void build(String name) {
15461            ComponentName componentName = ComponentName.unflattenFromString(name);
15462            if (componentName != null) {
15463                if (components == null) {
15464                    components = new ArrayList<ComponentName>();
15465                }
15466                components.add(componentName);
15467                all = false;
15468            } else {
15469                int objectId = 0;
15470                // Not a '/' separated full component name; maybe an object ID?
15471                try {
15472                    objectId = Integer.parseInt(name, 16);
15473                    if (objects == null) {
15474                        objects = new ArrayList<Integer>();
15475                    }
15476                    objects.add(objectId);
15477                    all = false;
15478                } catch (RuntimeException e) {
15479                    // Not an integer; just do string match.
15480                    if (strings == null) {
15481                        strings = new ArrayList<String>();
15482                    }
15483                    strings.add(name);
15484                    all = false;
15485                }
15486            }
15487        }
15488
15489        int build(String[] args, int opti) {
15490            for (; opti<args.length; opti++) {
15491                String name = args[opti];
15492                if ("--".equals(name)) {
15493                    return opti+1;
15494                }
15495                build(name);
15496            }
15497            return opti;
15498        }
15499
15500        boolean match(Object object, ComponentName comp) {
15501            if (all) {
15502                return true;
15503            }
15504            if (components != null) {
15505                for (int i=0; i<components.size(); i++) {
15506                    if (components.get(i).equals(comp)) {
15507                        return true;
15508                    }
15509                }
15510            }
15511            if (objects != null) {
15512                for (int i=0; i<objects.size(); i++) {
15513                    if (System.identityHashCode(object) == objects.get(i)) {
15514                        return true;
15515                    }
15516                }
15517            }
15518            if (strings != null) {
15519                String flat = comp.flattenToString();
15520                for (int i=0; i<strings.size(); i++) {
15521                    if (flat.contains(strings.get(i))) {
15522                        return true;
15523                    }
15524                }
15525            }
15526            return false;
15527        }
15528    }
15529
15530    /**
15531     * There are three things that cmd can be:
15532     *  - a flattened component name that matches an existing activity
15533     *  - the cmd arg isn't the flattened component name of an existing activity:
15534     *    dump all activity whose component contains the cmd as a substring
15535     *  - A hex number of the ActivityRecord object instance.
15536     */
15537    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15538            int opti, boolean dumpAll, boolean dumpVisibleStacks) {
15539        ArrayList<ActivityRecord> activities;
15540
15541        synchronized (this) {
15542            activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacks);
15543        }
15544
15545        if (activities.size() <= 0) {
15546            return false;
15547        }
15548
15549        String[] newArgs = new String[args.length - opti];
15550        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15551
15552        TaskRecord lastTask = null;
15553        boolean needSep = false;
15554        for (int i=activities.size()-1; i>=0; i--) {
15555            ActivityRecord r = activities.get(i);
15556            if (needSep) {
15557                pw.println();
15558            }
15559            needSep = true;
15560            synchronized (this) {
15561                if (lastTask != r.task) {
15562                    lastTask = r.task;
15563                    pw.print("TASK "); pw.print(lastTask.affinity);
15564                            pw.print(" id="); pw.print(lastTask.taskId);
15565                            pw.print(" userId="); pw.println(lastTask.userId);
15566                    if (dumpAll) {
15567                        lastTask.dump(pw, "  ");
15568                    }
15569                }
15570            }
15571            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
15572        }
15573        return true;
15574    }
15575
15576    /**
15577     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
15578     * there is a thread associated with the activity.
15579     */
15580    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
15581            final ActivityRecord r, String[] args, boolean dumpAll) {
15582        String innerPrefix = prefix + "  ";
15583        synchronized (this) {
15584            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
15585                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
15586                    pw.print(" pid=");
15587                    if (r.app != null) pw.println(r.app.pid);
15588                    else pw.println("(not running)");
15589            if (dumpAll) {
15590                r.dump(pw, innerPrefix);
15591            }
15592        }
15593        if (r.app != null && r.app.thread != null) {
15594            // flush anything that is already in the PrintWriter since the thread is going
15595            // to write to the file descriptor directly
15596            pw.flush();
15597            try {
15598                TransferPipe tp = new TransferPipe();
15599                try {
15600                    r.app.thread.dumpActivity(tp.getWriteFd(),
15601                            r.appToken, innerPrefix, args);
15602                    tp.go(fd);
15603                } finally {
15604                    tp.kill();
15605                }
15606            } catch (IOException e) {
15607                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
15608            } catch (RemoteException e) {
15609                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
15610            }
15611        }
15612    }
15613
15614    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15615            int opti, boolean dumpAll, String dumpPackage) {
15616        boolean needSep = false;
15617        boolean onlyHistory = false;
15618        boolean printedAnything = false;
15619
15620        if ("history".equals(dumpPackage)) {
15621            if (opti < args.length && "-s".equals(args[opti])) {
15622                dumpAll = false;
15623            }
15624            onlyHistory = true;
15625            dumpPackage = null;
15626        }
15627
15628        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
15629        if (!onlyHistory && dumpAll) {
15630            if (mRegisteredReceivers.size() > 0) {
15631                boolean printed = false;
15632                Iterator it = mRegisteredReceivers.values().iterator();
15633                while (it.hasNext()) {
15634                    ReceiverList r = (ReceiverList)it.next();
15635                    if (dumpPackage != null && (r.app == null ||
15636                            !dumpPackage.equals(r.app.info.packageName))) {
15637                        continue;
15638                    }
15639                    if (!printed) {
15640                        pw.println("  Registered Receivers:");
15641                        needSep = true;
15642                        printed = true;
15643                        printedAnything = true;
15644                    }
15645                    pw.print("  * "); pw.println(r);
15646                    r.dump(pw, "    ");
15647                }
15648            }
15649
15650            if (mReceiverResolver.dump(pw, needSep ?
15651                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
15652                    "    ", dumpPackage, false, false)) {
15653                needSep = true;
15654                printedAnything = true;
15655            }
15656        }
15657
15658        for (BroadcastQueue q : mBroadcastQueues) {
15659            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
15660            printedAnything |= needSep;
15661        }
15662
15663        needSep = true;
15664
15665        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15666            for (int user=0; user<mStickyBroadcasts.size(); user++) {
15667                if (needSep) {
15668                    pw.println();
15669                }
15670                needSep = true;
15671                printedAnything = true;
15672                pw.print("  Sticky broadcasts for user ");
15673                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15674                StringBuilder sb = new StringBuilder(128);
15675                for (Map.Entry<String, ArrayList<Intent>> ent
15676                        : mStickyBroadcasts.valueAt(user).entrySet()) {
15677                    pw.print("  * Sticky action "); pw.print(ent.getKey());
15678                    if (dumpAll) {
15679                        pw.println(":");
15680                        ArrayList<Intent> intents = ent.getValue();
15681                        final int N = intents.size();
15682                        for (int i=0; i<N; i++) {
15683                            sb.setLength(0);
15684                            sb.append("    Intent: ");
15685                            intents.get(i).toShortString(sb, false, true, false, false);
15686                            pw.println(sb.toString());
15687                            Bundle bundle = intents.get(i).getExtras();
15688                            if (bundle != null) {
15689                                pw.print("      ");
15690                                pw.println(bundle.toString());
15691                            }
15692                        }
15693                    } else {
15694                        pw.println("");
15695                    }
15696                }
15697            }
15698        }
15699
15700        if (!onlyHistory && dumpAll) {
15701            pw.println();
15702            for (BroadcastQueue queue : mBroadcastQueues) {
15703                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
15704                        + queue.mBroadcastsScheduled);
15705            }
15706            pw.println("  mHandler:");
15707            mHandler.dump(new PrintWriterPrinter(pw), "    ");
15708            needSep = true;
15709            printedAnything = true;
15710        }
15711
15712        if (!printedAnything) {
15713            pw.println("  (nothing)");
15714        }
15715    }
15716
15717    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15718            int opti, boolean dumpAll, String dumpPackage) {
15719        if (mCurBroadcastStats == null) {
15720            return;
15721        }
15722
15723        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15724        final long now = SystemClock.elapsedRealtime();
15725        if (mLastBroadcastStats != null) {
15726            pw.print("  Last stats (from ");
15727            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15728            pw.print(" to ");
15729            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15730            pw.print(", ");
15731            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15732                    - mLastBroadcastStats.mStartUptime, pw);
15733            pw.println(" uptime):");
15734            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15735                pw.println("    (nothing)");
15736            }
15737            pw.println();
15738        }
15739        pw.print("  Current stats (from ");
15740        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15741        pw.print(" to now, ");
15742        TimeUtils.formatDuration(SystemClock.uptimeMillis()
15743                - mCurBroadcastStats.mStartUptime, pw);
15744        pw.println(" uptime):");
15745        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15746            pw.println("    (nothing)");
15747        }
15748    }
15749
15750    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15751            int opti, boolean fullCheckin, String dumpPackage) {
15752        if (mCurBroadcastStats == null) {
15753            return;
15754        }
15755
15756        if (mLastBroadcastStats != null) {
15757            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15758            if (fullCheckin) {
15759                mLastBroadcastStats = null;
15760                return;
15761            }
15762        }
15763        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15764        if (fullCheckin) {
15765            mCurBroadcastStats = null;
15766        }
15767    }
15768
15769    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15770            int opti, boolean dumpAll, String dumpPackage) {
15771        boolean needSep;
15772        boolean printedAnything = false;
15773
15774        ItemMatcher matcher = new ItemMatcher();
15775        matcher.build(args, opti);
15776
15777        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15778
15779        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15780        printedAnything |= needSep;
15781
15782        if (mLaunchingProviders.size() > 0) {
15783            boolean printed = false;
15784            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15785                ContentProviderRecord r = mLaunchingProviders.get(i);
15786                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15787                    continue;
15788                }
15789                if (!printed) {
15790                    if (needSep) pw.println();
15791                    needSep = true;
15792                    pw.println("  Launching content providers:");
15793                    printed = true;
15794                    printedAnything = true;
15795                }
15796                pw.print("  Launching #"); pw.print(i); pw.print(": ");
15797                        pw.println(r);
15798            }
15799        }
15800
15801        if (!printedAnything) {
15802            pw.println("  (nothing)");
15803        }
15804    }
15805
15806    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15807            int opti, boolean dumpAll, String dumpPackage) {
15808        boolean needSep = false;
15809        boolean printedAnything = false;
15810
15811        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15812
15813        if (mGrantedUriPermissions.size() > 0) {
15814            boolean printed = false;
15815            int dumpUid = -2;
15816            if (dumpPackage != null) {
15817                try {
15818                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15819                            MATCH_ANY_USER, 0);
15820                } catch (NameNotFoundException e) {
15821                    dumpUid = -1;
15822                }
15823            }
15824            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15825                int uid = mGrantedUriPermissions.keyAt(i);
15826                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15827                    continue;
15828                }
15829                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15830                if (!printed) {
15831                    if (needSep) pw.println();
15832                    needSep = true;
15833                    pw.println("  Granted Uri Permissions:");
15834                    printed = true;
15835                    printedAnything = true;
15836                }
15837                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15838                for (UriPermission perm : perms.values()) {
15839                    pw.print("    "); pw.println(perm);
15840                    if (dumpAll) {
15841                        perm.dump(pw, "      ");
15842                    }
15843                }
15844            }
15845        }
15846
15847        if (!printedAnything) {
15848            pw.println("  (nothing)");
15849        }
15850    }
15851
15852    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15853            int opti, boolean dumpAll, String dumpPackage) {
15854        boolean printed = false;
15855
15856        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15857
15858        if (mIntentSenderRecords.size() > 0) {
15859            Iterator<WeakReference<PendingIntentRecord>> it
15860                    = mIntentSenderRecords.values().iterator();
15861            while (it.hasNext()) {
15862                WeakReference<PendingIntentRecord> ref = it.next();
15863                PendingIntentRecord rec = ref != null ? ref.get(): null;
15864                if (dumpPackage != null && (rec == null
15865                        || !dumpPackage.equals(rec.key.packageName))) {
15866                    continue;
15867                }
15868                printed = true;
15869                if (rec != null) {
15870                    pw.print("  * "); pw.println(rec);
15871                    if (dumpAll) {
15872                        rec.dump(pw, "    ");
15873                    }
15874                } else {
15875                    pw.print("  * "); pw.println(ref);
15876                }
15877            }
15878        }
15879
15880        if (!printed) {
15881            pw.println("  (nothing)");
15882        }
15883    }
15884
15885    private static final int dumpProcessList(PrintWriter pw,
15886            ActivityManagerService service, List list,
15887            String prefix, String normalLabel, String persistentLabel,
15888            String dumpPackage) {
15889        int numPers = 0;
15890        final int N = list.size()-1;
15891        for (int i=N; i>=0; i--) {
15892            ProcessRecord r = (ProcessRecord)list.get(i);
15893            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15894                continue;
15895            }
15896            pw.println(String.format("%s%s #%2d: %s",
15897                    prefix, (r.persistent ? persistentLabel : normalLabel),
15898                    i, r.toString()));
15899            if (r.persistent) {
15900                numPers++;
15901            }
15902        }
15903        return numPers;
15904    }
15905
15906    private static final boolean dumpProcessOomList(PrintWriter pw,
15907            ActivityManagerService service, List<ProcessRecord> origList,
15908            String prefix, String normalLabel, String persistentLabel,
15909            boolean inclDetails, String dumpPackage) {
15910
15911        ArrayList<Pair<ProcessRecord, Integer>> list
15912                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15913        for (int i=0; i<origList.size(); i++) {
15914            ProcessRecord r = origList.get(i);
15915            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15916                continue;
15917            }
15918            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15919        }
15920
15921        if (list.size() <= 0) {
15922            return false;
15923        }
15924
15925        Comparator<Pair<ProcessRecord, Integer>> comparator
15926                = new Comparator<Pair<ProcessRecord, Integer>>() {
15927            @Override
15928            public int compare(Pair<ProcessRecord, Integer> object1,
15929                    Pair<ProcessRecord, Integer> object2) {
15930                if (object1.first.setAdj != object2.first.setAdj) {
15931                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15932                }
15933                if (object1.first.setProcState != object2.first.setProcState) {
15934                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15935                }
15936                if (object1.second.intValue() != object2.second.intValue()) {
15937                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15938                }
15939                return 0;
15940            }
15941        };
15942
15943        Collections.sort(list, comparator);
15944
15945        final long curRealtime = SystemClock.elapsedRealtime();
15946        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15947        final long curUptime = SystemClock.uptimeMillis();
15948        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15949
15950        for (int i=list.size()-1; i>=0; i--) {
15951            ProcessRecord r = list.get(i).first;
15952            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15953            char schedGroup;
15954            switch (r.setSchedGroup) {
15955                case ProcessList.SCHED_GROUP_BACKGROUND:
15956                    schedGroup = 'B';
15957                    break;
15958                case ProcessList.SCHED_GROUP_DEFAULT:
15959                    schedGroup = 'F';
15960                    break;
15961                case ProcessList.SCHED_GROUP_TOP_APP:
15962                    schedGroup = 'T';
15963                    break;
15964                default:
15965                    schedGroup = '?';
15966                    break;
15967            }
15968            char foreground;
15969            if (r.foregroundActivities) {
15970                foreground = 'A';
15971            } else if (r.foregroundServices) {
15972                foreground = 'S';
15973            } else {
15974                foreground = ' ';
15975            }
15976            String procState = ProcessList.makeProcStateString(r.curProcState);
15977            pw.print(prefix);
15978            pw.print(r.persistent ? persistentLabel : normalLabel);
15979            pw.print(" #");
15980            int num = (origList.size()-1)-list.get(i).second;
15981            if (num < 10) pw.print(' ');
15982            pw.print(num);
15983            pw.print(": ");
15984            pw.print(oomAdj);
15985            pw.print(' ');
15986            pw.print(schedGroup);
15987            pw.print('/');
15988            pw.print(foreground);
15989            pw.print('/');
15990            pw.print(procState);
15991            pw.print(" trm:");
15992            if (r.trimMemoryLevel < 10) pw.print(' ');
15993            pw.print(r.trimMemoryLevel);
15994            pw.print(' ');
15995            pw.print(r.toShortString());
15996            pw.print(" (");
15997            pw.print(r.adjType);
15998            pw.println(')');
15999            if (r.adjSource != null || r.adjTarget != null) {
16000                pw.print(prefix);
16001                pw.print("    ");
16002                if (r.adjTarget instanceof ComponentName) {
16003                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
16004                } else if (r.adjTarget != null) {
16005                    pw.print(r.adjTarget.toString());
16006                } else {
16007                    pw.print("{null}");
16008                }
16009                pw.print("<=");
16010                if (r.adjSource instanceof ProcessRecord) {
16011                    pw.print("Proc{");
16012                    pw.print(((ProcessRecord)r.adjSource).toShortString());
16013                    pw.println("}");
16014                } else if (r.adjSource != null) {
16015                    pw.println(r.adjSource.toString());
16016                } else {
16017                    pw.println("{null}");
16018                }
16019            }
16020            if (inclDetails) {
16021                pw.print(prefix);
16022                pw.print("    ");
16023                pw.print("oom: max="); pw.print(r.maxAdj);
16024                pw.print(" curRaw="); pw.print(r.curRawAdj);
16025                pw.print(" setRaw="); pw.print(r.setRawAdj);
16026                pw.print(" cur="); pw.print(r.curAdj);
16027                pw.print(" set="); pw.println(r.setAdj);
16028                pw.print(prefix);
16029                pw.print("    ");
16030                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
16031                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
16032                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
16033                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
16034                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
16035                pw.println();
16036                pw.print(prefix);
16037                pw.print("    ");
16038                pw.print("cached="); pw.print(r.cached);
16039                pw.print(" empty="); pw.print(r.empty);
16040                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
16041
16042                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
16043                    if (r.lastWakeTime != 0) {
16044                        long wtime;
16045                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
16046                        synchronized (stats) {
16047                            wtime = stats.getProcessWakeTime(r.info.uid,
16048                                    r.pid, curRealtime);
16049                        }
16050                        long timeUsed = wtime - r.lastWakeTime;
16051                        pw.print(prefix);
16052                        pw.print("    ");
16053                        pw.print("keep awake over ");
16054                        TimeUtils.formatDuration(realtimeSince, pw);
16055                        pw.print(" used ");
16056                        TimeUtils.formatDuration(timeUsed, pw);
16057                        pw.print(" (");
16058                        pw.print((timeUsed*100)/realtimeSince);
16059                        pw.println("%)");
16060                    }
16061                    if (r.lastCpuTime != 0) {
16062                        long timeUsed = r.curCpuTime - r.lastCpuTime;
16063                        pw.print(prefix);
16064                        pw.print("    ");
16065                        pw.print("run cpu over ");
16066                        TimeUtils.formatDuration(uptimeSince, pw);
16067                        pw.print(" used ");
16068                        TimeUtils.formatDuration(timeUsed, pw);
16069                        pw.print(" (");
16070                        pw.print((timeUsed*100)/uptimeSince);
16071                        pw.println("%)");
16072                    }
16073                }
16074            }
16075        }
16076        return true;
16077    }
16078
16079    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
16080            String[] args) {
16081        ArrayList<ProcessRecord> procs;
16082        synchronized (this) {
16083            if (args != null && args.length > start
16084                    && args[start].charAt(0) != '-') {
16085                procs = new ArrayList<ProcessRecord>();
16086                int pid = -1;
16087                try {
16088                    pid = Integer.parseInt(args[start]);
16089                } catch (NumberFormatException e) {
16090                }
16091                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16092                    ProcessRecord proc = mLruProcesses.get(i);
16093                    if (proc.pid == pid) {
16094                        procs.add(proc);
16095                    } else if (allPkgs && proc.pkgList != null
16096                            && proc.pkgList.containsKey(args[start])) {
16097                        procs.add(proc);
16098                    } else if (proc.processName.equals(args[start])) {
16099                        procs.add(proc);
16100                    }
16101                }
16102                if (procs.size() <= 0) {
16103                    return null;
16104                }
16105            } else {
16106                procs = new ArrayList<ProcessRecord>(mLruProcesses);
16107            }
16108        }
16109        return procs;
16110    }
16111
16112    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
16113            PrintWriter pw, String[] args) {
16114        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16115        if (procs == null) {
16116            pw.println("No process found for: " + args[0]);
16117            return;
16118        }
16119
16120        long uptime = SystemClock.uptimeMillis();
16121        long realtime = SystemClock.elapsedRealtime();
16122        pw.println("Applications Graphics Acceleration Info:");
16123        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16124
16125        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16126            ProcessRecord r = procs.get(i);
16127            if (r.thread != null) {
16128                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
16129                pw.flush();
16130                try {
16131                    TransferPipe tp = new TransferPipe();
16132                    try {
16133                        r.thread.dumpGfxInfo(tp.getWriteFd(), args);
16134                        tp.go(fd);
16135                    } finally {
16136                        tp.kill();
16137                    }
16138                } catch (IOException e) {
16139                    pw.println("Failure while dumping the app: " + r);
16140                    pw.flush();
16141                } catch (RemoteException e) {
16142                    pw.println("Got a RemoteException while dumping the app " + r);
16143                    pw.flush();
16144                }
16145            }
16146        }
16147    }
16148
16149    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
16150        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16151        if (procs == null) {
16152            pw.println("No process found for: " + args[0]);
16153            return;
16154        }
16155
16156        pw.println("Applications Database Info:");
16157
16158        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16159            ProcessRecord r = procs.get(i);
16160            if (r.thread != null) {
16161                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
16162                pw.flush();
16163                try {
16164                    TransferPipe tp = new TransferPipe();
16165                    try {
16166                        r.thread.dumpDbInfo(tp.getWriteFd(), args);
16167                        tp.go(fd);
16168                    } finally {
16169                        tp.kill();
16170                    }
16171                } catch (IOException e) {
16172                    pw.println("Failure while dumping the app: " + r);
16173                    pw.flush();
16174                } catch (RemoteException e) {
16175                    pw.println("Got a RemoteException while dumping the app " + r);
16176                    pw.flush();
16177                }
16178            }
16179        }
16180    }
16181
16182    final static class MemItem {
16183        final boolean isProc;
16184        final String label;
16185        final String shortLabel;
16186        final long pss;
16187        final long swapPss;
16188        final int id;
16189        final boolean hasActivities;
16190        ArrayList<MemItem> subitems;
16191
16192        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
16193                boolean _hasActivities) {
16194            isProc = true;
16195            label = _label;
16196            shortLabel = _shortLabel;
16197            pss = _pss;
16198            swapPss = _swapPss;
16199            id = _id;
16200            hasActivities = _hasActivities;
16201        }
16202
16203        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
16204            isProc = false;
16205            label = _label;
16206            shortLabel = _shortLabel;
16207            pss = _pss;
16208            swapPss = _swapPss;
16209            id = _id;
16210            hasActivities = false;
16211        }
16212    }
16213
16214    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
16215            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
16216        if (sort && !isCompact) {
16217            Collections.sort(items, new Comparator<MemItem>() {
16218                @Override
16219                public int compare(MemItem lhs, MemItem rhs) {
16220                    if (lhs.pss < rhs.pss) {
16221                        return 1;
16222                    } else if (lhs.pss > rhs.pss) {
16223                        return -1;
16224                    }
16225                    return 0;
16226                }
16227            });
16228        }
16229
16230        for (int i=0; i<items.size(); i++) {
16231            MemItem mi = items.get(i);
16232            if (!isCompact) {
16233                if (dumpSwapPss) {
16234                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
16235                            mi.label, stringifyKBSize(mi.swapPss));
16236                } else {
16237                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
16238                }
16239            } else if (mi.isProc) {
16240                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
16241                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
16242                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
16243                pw.println(mi.hasActivities ? ",a" : ",e");
16244            } else {
16245                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
16246                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
16247            }
16248            if (mi.subitems != null) {
16249                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
16250                        true, isCompact, dumpSwapPss);
16251            }
16252        }
16253    }
16254
16255    // These are in KB.
16256    static final long[] DUMP_MEM_BUCKETS = new long[] {
16257        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
16258        120*1024, 160*1024, 200*1024,
16259        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
16260        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
16261    };
16262
16263    static final void appendMemBucket(StringBuilder out, long memKB, String label,
16264            boolean stackLike) {
16265        int start = label.lastIndexOf('.');
16266        if (start >= 0) start++;
16267        else start = 0;
16268        int end = label.length();
16269        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
16270            if (DUMP_MEM_BUCKETS[i] >= memKB) {
16271                long bucket = DUMP_MEM_BUCKETS[i]/1024;
16272                out.append(bucket);
16273                out.append(stackLike ? "MB." : "MB ");
16274                out.append(label, start, end);
16275                return;
16276            }
16277        }
16278        out.append(memKB/1024);
16279        out.append(stackLike ? "MB." : "MB ");
16280        out.append(label, start, end);
16281    }
16282
16283    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
16284            ProcessList.NATIVE_ADJ,
16285            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
16286            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
16287            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
16288            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
16289            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
16290            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
16291    };
16292    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
16293            "Native",
16294            "System", "Persistent", "Persistent Service", "Foreground",
16295            "Visible", "Perceptible",
16296            "Heavy Weight", "Backup",
16297            "A Services", "Home",
16298            "Previous", "B Services", "Cached"
16299    };
16300    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
16301            "native",
16302            "sys", "pers", "persvc", "fore",
16303            "vis", "percept",
16304            "heavy", "backup",
16305            "servicea", "home",
16306            "prev", "serviceb", "cached"
16307    };
16308
16309    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
16310            long realtime, boolean isCheckinRequest, boolean isCompact) {
16311        if (isCompact) {
16312            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
16313        }
16314        if (isCheckinRequest || isCompact) {
16315            // short checkin version
16316            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
16317        } else {
16318            pw.println("Applications Memory Usage (in Kilobytes):");
16319            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16320        }
16321    }
16322
16323    private static final int KSM_SHARED = 0;
16324    private static final int KSM_SHARING = 1;
16325    private static final int KSM_UNSHARED = 2;
16326    private static final int KSM_VOLATILE = 3;
16327
16328    private final long[] getKsmInfo() {
16329        long[] longOut = new long[4];
16330        final int[] SINGLE_LONG_FORMAT = new int[] {
16331            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
16332        };
16333        long[] longTmp = new long[1];
16334        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
16335                SINGLE_LONG_FORMAT, null, longTmp, null);
16336        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16337        longTmp[0] = 0;
16338        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
16339                SINGLE_LONG_FORMAT, null, longTmp, null);
16340        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16341        longTmp[0] = 0;
16342        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
16343                SINGLE_LONG_FORMAT, null, longTmp, null);
16344        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16345        longTmp[0] = 0;
16346        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
16347                SINGLE_LONG_FORMAT, null, longTmp, null);
16348        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16349        return longOut;
16350    }
16351
16352    private static String stringifySize(long size, int order) {
16353        Locale locale = Locale.US;
16354        switch (order) {
16355            case 1:
16356                return String.format(locale, "%,13d", size);
16357            case 1024:
16358                return String.format(locale, "%,9dK", size / 1024);
16359            case 1024 * 1024:
16360                return String.format(locale, "%,5dM", size / 1024 / 1024);
16361            case 1024 * 1024 * 1024:
16362                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
16363            default:
16364                throw new IllegalArgumentException("Invalid size order");
16365        }
16366    }
16367
16368    private static String stringifyKBSize(long size) {
16369        return stringifySize(size * 1024, 1024);
16370    }
16371
16372    // Update this version number in case you change the 'compact' format
16373    private static final int MEMINFO_COMPACT_VERSION = 1;
16374
16375    final void dumpApplicationMemoryUsage(FileDescriptor fd,
16376            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
16377        boolean dumpDetails = false;
16378        boolean dumpFullDetails = false;
16379        boolean dumpDalvik = false;
16380        boolean dumpSummaryOnly = false;
16381        boolean dumpUnreachable = false;
16382        boolean oomOnly = false;
16383        boolean isCompact = false;
16384        boolean localOnly = false;
16385        boolean packages = false;
16386        boolean isCheckinRequest = false;
16387        boolean dumpSwapPss = false;
16388
16389        int opti = 0;
16390        while (opti < args.length) {
16391            String opt = args[opti];
16392            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
16393                break;
16394            }
16395            opti++;
16396            if ("-a".equals(opt)) {
16397                dumpDetails = true;
16398                dumpFullDetails = true;
16399                dumpDalvik = true;
16400                dumpSwapPss = true;
16401            } else if ("-d".equals(opt)) {
16402                dumpDalvik = true;
16403            } else if ("-c".equals(opt)) {
16404                isCompact = true;
16405            } else if ("-s".equals(opt)) {
16406                dumpDetails = true;
16407                dumpSummaryOnly = true;
16408            } else if ("-S".equals(opt)) {
16409                dumpSwapPss = true;
16410            } else if ("--unreachable".equals(opt)) {
16411                dumpUnreachable = true;
16412            } else if ("--oom".equals(opt)) {
16413                oomOnly = true;
16414            } else if ("--local".equals(opt)) {
16415                localOnly = true;
16416            } else if ("--package".equals(opt)) {
16417                packages = true;
16418            } else if ("--checkin".equals(opt)) {
16419                isCheckinRequest = true;
16420
16421            } else if ("-h".equals(opt)) {
16422                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
16423                pw.println("  -a: include all available information for each process.");
16424                pw.println("  -d: include dalvik details.");
16425                pw.println("  -c: dump in a compact machine-parseable representation.");
16426                pw.println("  -s: dump only summary of application memory usage.");
16427                pw.println("  -S: dump also SwapPss.");
16428                pw.println("  --oom: only show processes organized by oom adj.");
16429                pw.println("  --local: only collect details locally, don't call process.");
16430                pw.println("  --package: interpret process arg as package, dumping all");
16431                pw.println("             processes that have loaded that package.");
16432                pw.println("  --checkin: dump data for a checkin");
16433                pw.println("If [process] is specified it can be the name or ");
16434                pw.println("pid of a specific process to dump.");
16435                return;
16436            } else {
16437                pw.println("Unknown argument: " + opt + "; use -h for help");
16438            }
16439        }
16440
16441        long uptime = SystemClock.uptimeMillis();
16442        long realtime = SystemClock.elapsedRealtime();
16443        final long[] tmpLong = new long[1];
16444
16445        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
16446        if (procs == null) {
16447            // No Java processes.  Maybe they want to print a native process.
16448            if (args != null && args.length > opti
16449                    && args[opti].charAt(0) != '-') {
16450                ArrayList<ProcessCpuTracker.Stats> nativeProcs
16451                        = new ArrayList<ProcessCpuTracker.Stats>();
16452                updateCpuStatsNow();
16453                int findPid = -1;
16454                try {
16455                    findPid = Integer.parseInt(args[opti]);
16456                } catch (NumberFormatException e) {
16457                }
16458                synchronized (mProcessCpuTracker) {
16459                    final int N = mProcessCpuTracker.countStats();
16460                    for (int i=0; i<N; i++) {
16461                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16462                        if (st.pid == findPid || (st.baseName != null
16463                                && st.baseName.equals(args[opti]))) {
16464                            nativeProcs.add(st);
16465                        }
16466                    }
16467                }
16468                if (nativeProcs.size() > 0) {
16469                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
16470                            isCompact);
16471                    Debug.MemoryInfo mi = null;
16472                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
16473                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
16474                        final int pid = r.pid;
16475                        if (!isCheckinRequest && dumpDetails) {
16476                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
16477                        }
16478                        if (mi == null) {
16479                            mi = new Debug.MemoryInfo();
16480                        }
16481                        if (dumpDetails || (!brief && !oomOnly)) {
16482                            Debug.getMemoryInfo(pid, mi);
16483                        } else {
16484                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16485                            mi.dalvikPrivateDirty = (int)tmpLong[0];
16486                        }
16487                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16488                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
16489                        if (isCheckinRequest) {
16490                            pw.println();
16491                        }
16492                    }
16493                    return;
16494                }
16495            }
16496            pw.println("No process found for: " + args[opti]);
16497            return;
16498        }
16499
16500        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
16501            dumpDetails = true;
16502        }
16503
16504        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
16505
16506        String[] innerArgs = new String[args.length-opti];
16507        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
16508
16509        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
16510        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
16511        long nativePss = 0;
16512        long nativeSwapPss = 0;
16513        long dalvikPss = 0;
16514        long dalvikSwapPss = 0;
16515        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16516                EmptyArray.LONG;
16517        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16518                EmptyArray.LONG;
16519        long otherPss = 0;
16520        long otherSwapPss = 0;
16521        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16522        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16523
16524        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16525        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16526        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
16527                new ArrayList[DUMP_MEM_OOM_LABEL.length];
16528
16529        long totalPss = 0;
16530        long totalSwapPss = 0;
16531        long cachedPss = 0;
16532        long cachedSwapPss = 0;
16533        boolean hasSwapPss = false;
16534
16535        Debug.MemoryInfo mi = null;
16536        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16537            final ProcessRecord r = procs.get(i);
16538            final IApplicationThread thread;
16539            final int pid;
16540            final int oomAdj;
16541            final boolean hasActivities;
16542            synchronized (this) {
16543                thread = r.thread;
16544                pid = r.pid;
16545                oomAdj = r.getSetAdjWithServices();
16546                hasActivities = r.activities.size() > 0;
16547            }
16548            if (thread != null) {
16549                if (!isCheckinRequest && dumpDetails) {
16550                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
16551                }
16552                if (mi == null) {
16553                    mi = new Debug.MemoryInfo();
16554                }
16555                if (dumpDetails || (!brief && !oomOnly)) {
16556                    Debug.getMemoryInfo(pid, mi);
16557                    hasSwapPss = mi.hasSwappedOutPss;
16558                } else {
16559                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16560                    mi.dalvikPrivateDirty = (int)tmpLong[0];
16561                }
16562                if (dumpDetails) {
16563                    if (localOnly) {
16564                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16565                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
16566                        if (isCheckinRequest) {
16567                            pw.println();
16568                        }
16569                    } else {
16570                        pw.flush();
16571                        try {
16572                            TransferPipe tp = new TransferPipe();
16573                            try {
16574                                thread.dumpMemInfo(tp.getWriteFd(),
16575                                        mi, isCheckinRequest, dumpFullDetails,
16576                                        dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
16577                                tp.go(fd);
16578                            } finally {
16579                                tp.kill();
16580                            }
16581                        } catch (IOException e) {
16582                            if (!isCheckinRequest) {
16583                                pw.println("Got IoException!");
16584                                pw.flush();
16585                            }
16586                        } catch (RemoteException e) {
16587                            if (!isCheckinRequest) {
16588                                pw.println("Got RemoteException!");
16589                                pw.flush();
16590                            }
16591                        }
16592                    }
16593                }
16594
16595                final long myTotalPss = mi.getTotalPss();
16596                final long myTotalUss = mi.getTotalUss();
16597                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16598
16599                synchronized (this) {
16600                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
16601                        // Record this for posterity if the process has been stable.
16602                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
16603                    }
16604                }
16605
16606                if (!isCheckinRequest && mi != null) {
16607                    totalPss += myTotalPss;
16608                    totalSwapPss += myTotalSwapPss;
16609                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
16610                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
16611                            myTotalSwapPss, pid, hasActivities);
16612                    procMems.add(pssItem);
16613                    procMemsMap.put(pid, pssItem);
16614
16615                    nativePss += mi.nativePss;
16616                    nativeSwapPss += mi.nativeSwappedOutPss;
16617                    dalvikPss += mi.dalvikPss;
16618                    dalvikSwapPss += mi.dalvikSwappedOutPss;
16619                    for (int j=0; j<dalvikSubitemPss.length; j++) {
16620                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16621                        dalvikSubitemSwapPss[j] +=
16622                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16623                    }
16624                    otherPss += mi.otherPss;
16625                    otherSwapPss += mi.otherSwappedOutPss;
16626                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16627                        long mem = mi.getOtherPss(j);
16628                        miscPss[j] += mem;
16629                        otherPss -= mem;
16630                        mem = mi.getOtherSwappedOutPss(j);
16631                        miscSwapPss[j] += mem;
16632                        otherSwapPss -= mem;
16633                    }
16634
16635                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16636                        cachedPss += myTotalPss;
16637                        cachedSwapPss += myTotalSwapPss;
16638                    }
16639
16640                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
16641                        if (oomIndex == (oomPss.length - 1)
16642                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
16643                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
16644                            oomPss[oomIndex] += myTotalPss;
16645                            oomSwapPss[oomIndex] += myTotalSwapPss;
16646                            if (oomProcs[oomIndex] == null) {
16647                                oomProcs[oomIndex] = new ArrayList<MemItem>();
16648                            }
16649                            oomProcs[oomIndex].add(pssItem);
16650                            break;
16651                        }
16652                    }
16653                }
16654            }
16655        }
16656
16657        long nativeProcTotalPss = 0;
16658
16659        if (!isCheckinRequest && procs.size() > 1 && !packages) {
16660            // If we are showing aggregations, also look for native processes to
16661            // include so that our aggregations are more accurate.
16662            updateCpuStatsNow();
16663            mi = null;
16664            synchronized (mProcessCpuTracker) {
16665                final int N = mProcessCpuTracker.countStats();
16666                for (int i=0; i<N; i++) {
16667                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16668                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
16669                        if (mi == null) {
16670                            mi = new Debug.MemoryInfo();
16671                        }
16672                        if (!brief && !oomOnly) {
16673                            Debug.getMemoryInfo(st.pid, mi);
16674                        } else {
16675                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
16676                            mi.nativePrivateDirty = (int)tmpLong[0];
16677                        }
16678
16679                        final long myTotalPss = mi.getTotalPss();
16680                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16681                        totalPss += myTotalPss;
16682                        nativeProcTotalPss += myTotalPss;
16683
16684                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16685                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16686                        procMems.add(pssItem);
16687
16688                        nativePss += mi.nativePss;
16689                        nativeSwapPss += mi.nativeSwappedOutPss;
16690                        dalvikPss += mi.dalvikPss;
16691                        dalvikSwapPss += mi.dalvikSwappedOutPss;
16692                        for (int j=0; j<dalvikSubitemPss.length; j++) {
16693                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16694                            dalvikSubitemSwapPss[j] +=
16695                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16696                        }
16697                        otherPss += mi.otherPss;
16698                        otherSwapPss += mi.otherSwappedOutPss;
16699                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16700                            long mem = mi.getOtherPss(j);
16701                            miscPss[j] += mem;
16702                            otherPss -= mem;
16703                            mem = mi.getOtherSwappedOutPss(j);
16704                            miscSwapPss[j] += mem;
16705                            otherSwapPss -= mem;
16706                        }
16707                        oomPss[0] += myTotalPss;
16708                        oomSwapPss[0] += myTotalSwapPss;
16709                        if (oomProcs[0] == null) {
16710                            oomProcs[0] = new ArrayList<MemItem>();
16711                        }
16712                        oomProcs[0].add(pssItem);
16713                    }
16714                }
16715            }
16716
16717            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16718
16719            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16720            final MemItem dalvikItem =
16721                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16722            if (dalvikSubitemPss.length > 0) {
16723                dalvikItem.subitems = new ArrayList<MemItem>();
16724                for (int j=0; j<dalvikSubitemPss.length; j++) {
16725                    final String name = Debug.MemoryInfo.getOtherLabel(
16726                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
16727                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16728                                    dalvikSubitemSwapPss[j], j));
16729                }
16730            }
16731            catMems.add(dalvikItem);
16732            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16733            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16734                String label = Debug.MemoryInfo.getOtherLabel(j);
16735                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16736            }
16737
16738            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16739            for (int j=0; j<oomPss.length; j++) {
16740                if (oomPss[j] != 0) {
16741                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16742                            : DUMP_MEM_OOM_LABEL[j];
16743                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16744                            DUMP_MEM_OOM_ADJ[j]);
16745                    item.subitems = oomProcs[j];
16746                    oomMems.add(item);
16747                }
16748            }
16749
16750            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16751            if (!brief && !oomOnly && !isCompact) {
16752                pw.println();
16753                pw.println("Total PSS by process:");
16754                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
16755                pw.println();
16756            }
16757            if (!isCompact) {
16758                pw.println("Total PSS by OOM adjustment:");
16759            }
16760            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
16761            if (!brief && !oomOnly) {
16762                PrintWriter out = categoryPw != null ? categoryPw : pw;
16763                if (!isCompact) {
16764                    out.println();
16765                    out.println("Total PSS by category:");
16766                }
16767                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
16768            }
16769            if (!isCompact) {
16770                pw.println();
16771            }
16772            MemInfoReader memInfo = new MemInfoReader();
16773            memInfo.readMemInfo();
16774            if (nativeProcTotalPss > 0) {
16775                synchronized (this) {
16776                    final long cachedKb = memInfo.getCachedSizeKb();
16777                    final long freeKb = memInfo.getFreeSizeKb();
16778                    final long zramKb = memInfo.getZramTotalSizeKb();
16779                    final long kernelKb = memInfo.getKernelUsedSizeKb();
16780                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16781                            kernelKb*1024, nativeProcTotalPss*1024);
16782                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16783                            nativeProcTotalPss);
16784                }
16785            }
16786            if (!brief) {
16787                if (!isCompact) {
16788                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16789                    pw.print(" (status ");
16790                    switch (mLastMemoryLevel) {
16791                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16792                            pw.println("normal)");
16793                            break;
16794                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16795                            pw.println("moderate)");
16796                            break;
16797                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
16798                            pw.println("low)");
16799                            break;
16800                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16801                            pw.println("critical)");
16802                            break;
16803                        default:
16804                            pw.print(mLastMemoryLevel);
16805                            pw.println(")");
16806                            break;
16807                    }
16808                    pw.print(" Free RAM: ");
16809                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16810                            + memInfo.getFreeSizeKb()));
16811                    pw.print(" (");
16812                    pw.print(stringifyKBSize(cachedPss));
16813                    pw.print(" cached pss + ");
16814                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16815                    pw.print(" cached kernel + ");
16816                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16817                    pw.println(" free)");
16818                } else {
16819                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16820                    pw.print(cachedPss + memInfo.getCachedSizeKb()
16821                            + memInfo.getFreeSizeKb()); pw.print(",");
16822                    pw.println(totalPss - cachedPss);
16823                }
16824            }
16825            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16826                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16827                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16828            if (!isCompact) {
16829                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16830                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16831                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16832                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16833                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16834            } else {
16835                pw.print("lostram,"); pw.println(lostRAM);
16836            }
16837            if (!brief) {
16838                if (memInfo.getZramTotalSizeKb() != 0) {
16839                    if (!isCompact) {
16840                        pw.print("     ZRAM: ");
16841                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16842                                pw.print(" physical used for ");
16843                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16844                                        - memInfo.getSwapFreeSizeKb()));
16845                                pw.print(" in swap (");
16846                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16847                                pw.println(" total swap)");
16848                    } else {
16849                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16850                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16851                                pw.println(memInfo.getSwapFreeSizeKb());
16852                    }
16853                }
16854                final long[] ksm = getKsmInfo();
16855                if (!isCompact) {
16856                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16857                            || ksm[KSM_VOLATILE] != 0) {
16858                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16859                                pw.print(" saved from shared ");
16860                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16861                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16862                                pw.print(" unshared; ");
16863                                pw.print(stringifyKBSize(
16864                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
16865                    }
16866                    pw.print("   Tuning: ");
16867                    pw.print(ActivityManager.staticGetMemoryClass());
16868                    pw.print(" (large ");
16869                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16870                    pw.print("), oom ");
16871                    pw.print(stringifySize(
16872                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16873                    pw.print(", restore limit ");
16874                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16875                    if (ActivityManager.isLowRamDeviceStatic()) {
16876                        pw.print(" (low-ram)");
16877                    }
16878                    if (ActivityManager.isHighEndGfx()) {
16879                        pw.print(" (high-end-gfx)");
16880                    }
16881                    pw.println();
16882                } else {
16883                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16884                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16885                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16886                    pw.print("tuning,");
16887                    pw.print(ActivityManager.staticGetMemoryClass());
16888                    pw.print(',');
16889                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16890                    pw.print(',');
16891                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16892                    if (ActivityManager.isLowRamDeviceStatic()) {
16893                        pw.print(",low-ram");
16894                    }
16895                    if (ActivityManager.isHighEndGfx()) {
16896                        pw.print(",high-end-gfx");
16897                    }
16898                    pw.println();
16899                }
16900            }
16901        }
16902    }
16903
16904    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16905            long memtrack, String name) {
16906        sb.append("  ");
16907        sb.append(ProcessList.makeOomAdjString(oomAdj));
16908        sb.append(' ');
16909        sb.append(ProcessList.makeProcStateString(procState));
16910        sb.append(' ');
16911        ProcessList.appendRamKb(sb, pss);
16912        sb.append(": ");
16913        sb.append(name);
16914        if (memtrack > 0) {
16915            sb.append(" (");
16916            sb.append(stringifyKBSize(memtrack));
16917            sb.append(" memtrack)");
16918        }
16919    }
16920
16921    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16922        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16923        sb.append(" (pid ");
16924        sb.append(mi.pid);
16925        sb.append(") ");
16926        sb.append(mi.adjType);
16927        sb.append('\n');
16928        if (mi.adjReason != null) {
16929            sb.append("                      ");
16930            sb.append(mi.adjReason);
16931            sb.append('\n');
16932        }
16933    }
16934
16935    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16936        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16937        for (int i=0, N=memInfos.size(); i<N; i++) {
16938            ProcessMemInfo mi = memInfos.get(i);
16939            infoMap.put(mi.pid, mi);
16940        }
16941        updateCpuStatsNow();
16942        long[] memtrackTmp = new long[1];
16943        final List<ProcessCpuTracker.Stats> stats;
16944        // Get a list of Stats that have vsize > 0
16945        synchronized (mProcessCpuTracker) {
16946            stats = mProcessCpuTracker.getStats((st) -> {
16947                return st.vsize > 0;
16948            });
16949        }
16950        final int statsCount = stats.size();
16951        for (int i = 0; i < statsCount; i++) {
16952            ProcessCpuTracker.Stats st = stats.get(i);
16953            long pss = Debug.getPss(st.pid, null, memtrackTmp);
16954            if (pss > 0) {
16955                if (infoMap.indexOfKey(st.pid) < 0) {
16956                    ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16957                            ProcessList.NATIVE_ADJ, -1, "native", null);
16958                    mi.pss = pss;
16959                    mi.memtrack = memtrackTmp[0];
16960                    memInfos.add(mi);
16961                }
16962            }
16963        }
16964
16965        long totalPss = 0;
16966        long totalMemtrack = 0;
16967        for (int i=0, N=memInfos.size(); i<N; i++) {
16968            ProcessMemInfo mi = memInfos.get(i);
16969            if (mi.pss == 0) {
16970                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16971                mi.memtrack = memtrackTmp[0];
16972            }
16973            totalPss += mi.pss;
16974            totalMemtrack += mi.memtrack;
16975        }
16976        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16977            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16978                if (lhs.oomAdj != rhs.oomAdj) {
16979                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16980                }
16981                if (lhs.pss != rhs.pss) {
16982                    return lhs.pss < rhs.pss ? 1 : -1;
16983                }
16984                return 0;
16985            }
16986        });
16987
16988        StringBuilder tag = new StringBuilder(128);
16989        StringBuilder stack = new StringBuilder(128);
16990        tag.append("Low on memory -- ");
16991        appendMemBucket(tag, totalPss, "total", false);
16992        appendMemBucket(stack, totalPss, "total", true);
16993
16994        StringBuilder fullNativeBuilder = new StringBuilder(1024);
16995        StringBuilder shortNativeBuilder = new StringBuilder(1024);
16996        StringBuilder fullJavaBuilder = new StringBuilder(1024);
16997
16998        boolean firstLine = true;
16999        int lastOomAdj = Integer.MIN_VALUE;
17000        long extraNativeRam = 0;
17001        long extraNativeMemtrack = 0;
17002        long cachedPss = 0;
17003        for (int i=0, N=memInfos.size(); i<N; i++) {
17004            ProcessMemInfo mi = memInfos.get(i);
17005
17006            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17007                cachedPss += mi.pss;
17008            }
17009
17010            if (mi.oomAdj != ProcessList.NATIVE_ADJ
17011                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
17012                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
17013                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
17014                if (lastOomAdj != mi.oomAdj) {
17015                    lastOomAdj = mi.oomAdj;
17016                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17017                        tag.append(" / ");
17018                    }
17019                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
17020                        if (firstLine) {
17021                            stack.append(":");
17022                            firstLine = false;
17023                        }
17024                        stack.append("\n\t at ");
17025                    } else {
17026                        stack.append("$");
17027                    }
17028                } else {
17029                    tag.append(" ");
17030                    stack.append("$");
17031                }
17032                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17033                    appendMemBucket(tag, mi.pss, mi.name, false);
17034                }
17035                appendMemBucket(stack, mi.pss, mi.name, true);
17036                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
17037                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
17038                    stack.append("(");
17039                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
17040                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
17041                            stack.append(DUMP_MEM_OOM_LABEL[k]);
17042                            stack.append(":");
17043                            stack.append(DUMP_MEM_OOM_ADJ[k]);
17044                        }
17045                    }
17046                    stack.append(")");
17047                }
17048            }
17049
17050            appendMemInfo(fullNativeBuilder, mi);
17051            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
17052                // The short form only has native processes that are >= 512K.
17053                if (mi.pss >= 512) {
17054                    appendMemInfo(shortNativeBuilder, mi);
17055                } else {
17056                    extraNativeRam += mi.pss;
17057                    extraNativeMemtrack += mi.memtrack;
17058                }
17059            } else {
17060                // Short form has all other details, but if we have collected RAM
17061                // from smaller native processes let's dump a summary of that.
17062                if (extraNativeRam > 0) {
17063                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
17064                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
17065                    shortNativeBuilder.append('\n');
17066                    extraNativeRam = 0;
17067                }
17068                appendMemInfo(fullJavaBuilder, mi);
17069            }
17070        }
17071
17072        fullJavaBuilder.append("           ");
17073        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
17074        fullJavaBuilder.append(": TOTAL");
17075        if (totalMemtrack > 0) {
17076            fullJavaBuilder.append(" (");
17077            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
17078            fullJavaBuilder.append(" memtrack)");
17079        } else {
17080        }
17081        fullJavaBuilder.append("\n");
17082
17083        MemInfoReader memInfo = new MemInfoReader();
17084        memInfo.readMemInfo();
17085        final long[] infos = memInfo.getRawInfo();
17086
17087        StringBuilder memInfoBuilder = new StringBuilder(1024);
17088        Debug.getMemInfo(infos);
17089        memInfoBuilder.append("  MemInfo: ");
17090        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
17091        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
17092        memInfoBuilder.append(stringifyKBSize(
17093                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
17094        memInfoBuilder.append(stringifyKBSize(
17095                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
17096        memInfoBuilder.append(stringifyKBSize(
17097                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
17098        memInfoBuilder.append("           ");
17099        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
17100        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
17101        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
17102        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
17103        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
17104            memInfoBuilder.append("  ZRAM: ");
17105            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
17106            memInfoBuilder.append(" RAM, ");
17107            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
17108            memInfoBuilder.append(" swap total, ");
17109            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
17110            memInfoBuilder.append(" swap free\n");
17111        }
17112        final long[] ksm = getKsmInfo();
17113        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17114                || ksm[KSM_VOLATILE] != 0) {
17115            memInfoBuilder.append("  KSM: ");
17116            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
17117            memInfoBuilder.append(" saved from shared ");
17118            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
17119            memInfoBuilder.append("\n       ");
17120            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
17121            memInfoBuilder.append(" unshared; ");
17122            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
17123            memInfoBuilder.append(" volatile\n");
17124        }
17125        memInfoBuilder.append("  Free RAM: ");
17126        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17127                + memInfo.getFreeSizeKb()));
17128        memInfoBuilder.append("\n");
17129        memInfoBuilder.append("  Used RAM: ");
17130        memInfoBuilder.append(stringifyKBSize(
17131                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
17132        memInfoBuilder.append("\n");
17133        memInfoBuilder.append("  Lost RAM: ");
17134        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
17135                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17136                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
17137        memInfoBuilder.append("\n");
17138        Slog.i(TAG, "Low on memory:");
17139        Slog.i(TAG, shortNativeBuilder.toString());
17140        Slog.i(TAG, fullJavaBuilder.toString());
17141        Slog.i(TAG, memInfoBuilder.toString());
17142
17143        StringBuilder dropBuilder = new StringBuilder(1024);
17144        /*
17145        StringWriter oomSw = new StringWriter();
17146        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
17147        StringWriter catSw = new StringWriter();
17148        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17149        String[] emptyArgs = new String[] { };
17150        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
17151        oomPw.flush();
17152        String oomString = oomSw.toString();
17153        */
17154        dropBuilder.append("Low on memory:");
17155        dropBuilder.append(stack);
17156        dropBuilder.append('\n');
17157        dropBuilder.append(fullNativeBuilder);
17158        dropBuilder.append(fullJavaBuilder);
17159        dropBuilder.append('\n');
17160        dropBuilder.append(memInfoBuilder);
17161        dropBuilder.append('\n');
17162        /*
17163        dropBuilder.append(oomString);
17164        dropBuilder.append('\n');
17165        */
17166        StringWriter catSw = new StringWriter();
17167        synchronized (ActivityManagerService.this) {
17168            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17169            String[] emptyArgs = new String[] { };
17170            catPw.println();
17171            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
17172            catPw.println();
17173            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
17174                    false, null).dumpLocked();
17175            catPw.println();
17176            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
17177            catPw.flush();
17178        }
17179        dropBuilder.append(catSw.toString());
17180        addErrorToDropBox("lowmem", null, "system_server", null,
17181                null, tag.toString(), dropBuilder.toString(), null, null);
17182        //Slog.i(TAG, "Sent to dropbox:");
17183        //Slog.i(TAG, dropBuilder.toString());
17184        synchronized (ActivityManagerService.this) {
17185            long now = SystemClock.uptimeMillis();
17186            if (mLastMemUsageReportTime < now) {
17187                mLastMemUsageReportTime = now;
17188            }
17189        }
17190    }
17191
17192    /**
17193     * Searches array of arguments for the specified string
17194     * @param args array of argument strings
17195     * @param value value to search for
17196     * @return true if the value is contained in the array
17197     */
17198    private static boolean scanArgs(String[] args, String value) {
17199        if (args != null) {
17200            for (String arg : args) {
17201                if (value.equals(arg)) {
17202                    return true;
17203                }
17204            }
17205        }
17206        return false;
17207    }
17208
17209    private final boolean removeDyingProviderLocked(ProcessRecord proc,
17210            ContentProviderRecord cpr, boolean always) {
17211        final boolean inLaunching = mLaunchingProviders.contains(cpr);
17212
17213        if (!inLaunching || always) {
17214            synchronized (cpr) {
17215                cpr.launchingApp = null;
17216                cpr.notifyAll();
17217            }
17218            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
17219            String names[] = cpr.info.authority.split(";");
17220            for (int j = 0; j < names.length; j++) {
17221                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
17222            }
17223        }
17224
17225        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
17226            ContentProviderConnection conn = cpr.connections.get(i);
17227            if (conn.waiting) {
17228                // If this connection is waiting for the provider, then we don't
17229                // need to mess with its process unless we are always removing
17230                // or for some reason the provider is not currently launching.
17231                if (inLaunching && !always) {
17232                    continue;
17233                }
17234            }
17235            ProcessRecord capp = conn.client;
17236            conn.dead = true;
17237            if (conn.stableCount > 0) {
17238                if (!capp.persistent && capp.thread != null
17239                        && capp.pid != 0
17240                        && capp.pid != MY_PID) {
17241                    capp.kill("depends on provider "
17242                            + cpr.name.flattenToShortString()
17243                            + " in dying proc " + (proc != null ? proc.processName : "??")
17244                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
17245                }
17246            } else if (capp.thread != null && conn.provider.provider != null) {
17247                try {
17248                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
17249                } catch (RemoteException e) {
17250                }
17251                // In the protocol here, we don't expect the client to correctly
17252                // clean up this connection, we'll just remove it.
17253                cpr.connections.remove(i);
17254                if (conn.client.conProviders.remove(conn)) {
17255                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
17256                }
17257            }
17258        }
17259
17260        if (inLaunching && always) {
17261            mLaunchingProviders.remove(cpr);
17262        }
17263        return inLaunching;
17264    }
17265
17266    /**
17267     * Main code for cleaning up a process when it has gone away.  This is
17268     * called both as a result of the process dying, or directly when stopping
17269     * a process when running in single process mode.
17270     *
17271     * @return Returns true if the given process has been restarted, so the
17272     * app that was passed in must remain on the process lists.
17273     */
17274    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
17275            boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
17276        Slog.d(TAG, "cleanUpApplicationRecord -- " + app.pid);
17277        if (index >= 0) {
17278            removeLruProcessLocked(app);
17279            ProcessList.remove(app.pid);
17280        }
17281
17282        mProcessesToGc.remove(app);
17283        mPendingPssProcesses.remove(app);
17284
17285        // Dismiss any open dialogs.
17286        if (app.crashDialog != null && !app.forceCrashReport) {
17287            app.crashDialog.dismiss();
17288            app.crashDialog = null;
17289        }
17290        if (app.anrDialog != null) {
17291            app.anrDialog.dismiss();
17292            app.anrDialog = null;
17293        }
17294        if (app.waitDialog != null) {
17295            app.waitDialog.dismiss();
17296            app.waitDialog = null;
17297        }
17298
17299        app.crashing = false;
17300        app.notResponding = false;
17301
17302        app.resetPackageList(mProcessStats);
17303        app.unlinkDeathRecipient();
17304        app.makeInactive(mProcessStats);
17305        app.waitingToKill = null;
17306        app.forcingToForeground = null;
17307        updateProcessForegroundLocked(app, false, false);
17308        app.foregroundActivities = false;
17309        app.hasShownUi = false;
17310        app.treatLikeActivity = false;
17311        app.hasAboveClient = false;
17312        app.hasClientActivities = false;
17313
17314        mServices.killServicesLocked(app, allowRestart);
17315
17316        boolean restart = false;
17317
17318        // Remove published content providers.
17319        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
17320            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
17321            final boolean always = app.bad || !allowRestart;
17322            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
17323            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
17324                // We left the provider in the launching list, need to
17325                // restart it.
17326                restart = true;
17327            }
17328
17329            cpr.provider = null;
17330            cpr.proc = null;
17331        }
17332        app.pubProviders.clear();
17333
17334        // Take care of any launching providers waiting for this process.
17335        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
17336            restart = true;
17337        }
17338
17339        // Unregister from connected content providers.
17340        if (!app.conProviders.isEmpty()) {
17341            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
17342                ContentProviderConnection conn = app.conProviders.get(i);
17343                conn.provider.connections.remove(conn);
17344                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
17345                        conn.provider.name);
17346            }
17347            app.conProviders.clear();
17348        }
17349
17350        // At this point there may be remaining entries in mLaunchingProviders
17351        // where we were the only one waiting, so they are no longer of use.
17352        // Look for these and clean up if found.
17353        // XXX Commented out for now.  Trying to figure out a way to reproduce
17354        // the actual situation to identify what is actually going on.
17355        if (false) {
17356            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17357                ContentProviderRecord cpr = mLaunchingProviders.get(i);
17358                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
17359                    synchronized (cpr) {
17360                        cpr.launchingApp = null;
17361                        cpr.notifyAll();
17362                    }
17363                }
17364            }
17365        }
17366
17367        skipCurrentReceiverLocked(app);
17368
17369        // Unregister any receivers.
17370        for (int i = app.receivers.size() - 1; i >= 0; i--) {
17371            removeReceiverLocked(app.receivers.valueAt(i));
17372        }
17373        app.receivers.clear();
17374
17375        // If the app is undergoing backup, tell the backup manager about it
17376        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
17377            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
17378                    + mBackupTarget.appInfo + " died during backup");
17379            mHandler.post(new Runnable() {
17380                @Override
17381                public void run(){
17382                    try {
17383                        IBackupManager bm = IBackupManager.Stub.asInterface(
17384                                ServiceManager.getService(Context.BACKUP_SERVICE));
17385                        bm.agentDisconnected(app.info.packageName);
17386                    } catch (RemoteException e) {
17387                        // can't happen; backup manager is local
17388                    }
17389                }
17390            });
17391        }
17392
17393        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
17394            ProcessChangeItem item = mPendingProcessChanges.get(i);
17395            if (item.pid == app.pid) {
17396                mPendingProcessChanges.remove(i);
17397                mAvailProcessChanges.add(item);
17398            }
17399        }
17400        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
17401                null).sendToTarget();
17402
17403        // If the caller is restarting this app, then leave it in its
17404        // current lists and let the caller take care of it.
17405        if (restarting) {
17406            return false;
17407        }
17408
17409        if (!app.persistent || app.isolated) {
17410            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
17411                    "Removing non-persistent process during cleanup: " + app);
17412            if (!replacingPid) {
17413                removeProcessNameLocked(app.processName, app.uid, app);
17414            }
17415            if (mHeavyWeightProcess == app) {
17416                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
17417                        mHeavyWeightProcess.userId, 0));
17418                mHeavyWeightProcess = null;
17419            }
17420        } else if (!app.removed) {
17421            // This app is persistent, so we need to keep its record around.
17422            // If it is not already on the pending app list, add it there
17423            // and start a new process for it.
17424            if (mPersistentStartingProcesses.indexOf(app) < 0) {
17425                mPersistentStartingProcesses.add(app);
17426                restart = true;
17427            }
17428        }
17429        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
17430                TAG_CLEANUP, "Clean-up removing on hold: " + app);
17431        mProcessesOnHold.remove(app);
17432
17433        if (app == mHomeProcess) {
17434            mHomeProcess = null;
17435        }
17436        if (app == mPreviousProcess) {
17437            mPreviousProcess = null;
17438        }
17439
17440        if (restart && !app.isolated) {
17441            // We have components that still need to be running in the
17442            // process, so re-launch it.
17443            if (index < 0) {
17444                ProcessList.remove(app.pid);
17445            }
17446            addProcessNameLocked(app);
17447            startProcessLocked(app, "restart", app.processName);
17448            return true;
17449        } else if (app.pid > 0 && app.pid != MY_PID) {
17450            // Goodbye!
17451            boolean removed;
17452            synchronized (mPidsSelfLocked) {
17453                mPidsSelfLocked.remove(app.pid);
17454                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
17455            }
17456            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
17457            if (app.isolated) {
17458                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
17459            }
17460            app.setPid(0);
17461        }
17462        return false;
17463    }
17464
17465    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
17466        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17467            ContentProviderRecord cpr = mLaunchingProviders.get(i);
17468            if (cpr.launchingApp == app) {
17469                return true;
17470            }
17471        }
17472        return false;
17473    }
17474
17475    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
17476        // Look through the content providers we are waiting to have launched,
17477        // and if any run in this process then either schedule a restart of
17478        // the process or kill the client waiting for it if this process has
17479        // gone bad.
17480        boolean restart = false;
17481        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17482            ContentProviderRecord cpr = mLaunchingProviders.get(i);
17483            if (cpr.launchingApp == app) {
17484                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
17485                    restart = true;
17486                } else {
17487                    removeDyingProviderLocked(app, cpr, true);
17488                }
17489            }
17490        }
17491        return restart;
17492    }
17493
17494    // =========================================================
17495    // SERVICES
17496    // =========================================================
17497
17498    @Override
17499    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
17500            int flags) {
17501        enforceNotIsolatedCaller("getServices");
17502        synchronized (this) {
17503            final int callingUid = Binder.getCallingUid();
17504            final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
17505                callingUid);
17506
17507            return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid, allowed);
17508        }
17509    }
17510
17511    @Override
17512    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
17513        enforceNotIsolatedCaller("getRunningServiceControlPanel");
17514        synchronized (this) {
17515            return mServices.getRunningServiceControlPanelLocked(name);
17516        }
17517    }
17518
17519    @Override
17520    public ComponentName startService(IApplicationThread caller, Intent service,
17521            String resolvedType, int id, Notification notification,
17522            String callingPackage, int userId)
17523            throws TransactionTooLargeException {
17524        enforceNotIsolatedCaller("startService");
17525        // Refuse possible leaked file descriptors
17526        if (service != null && service.hasFileDescriptors() == true) {
17527            throw new IllegalArgumentException("File descriptors passed in Intent");
17528        }
17529
17530        if (callingPackage == null) {
17531            throw new IllegalArgumentException("callingPackage cannot be null");
17532        }
17533
17534        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17535                "startService: " + service + " type=" + resolvedType);
17536        synchronized(this) {
17537            final int callingPid = Binder.getCallingPid();
17538            final int callingUid = Binder.getCallingUid();
17539            final long origId = Binder.clearCallingIdentity();
17540            ComponentName res = mServices.startServiceLocked(caller, service,
17541                    resolvedType, id, notification,
17542                    callingPid, callingUid, callingPackage, userId);
17543            Binder.restoreCallingIdentity(origId);
17544            return res;
17545        }
17546    }
17547
17548    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
17549            String callingPackage, int userId)
17550            throws TransactionTooLargeException {
17551        synchronized(this) {
17552            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17553                    "startServiceInPackage: " + service + " type=" + resolvedType);
17554            final long origId = Binder.clearCallingIdentity();
17555            ComponentName res = mServices.startServiceLocked(null, service,
17556                    resolvedType, 0, null, -1, uid, callingPackage, userId);
17557            Binder.restoreCallingIdentity(origId);
17558            return res;
17559        }
17560    }
17561
17562    @Override
17563    public int stopService(IApplicationThread caller, Intent service,
17564            String resolvedType, int userId) {
17565        enforceNotIsolatedCaller("stopService");
17566        // Refuse possible leaked file descriptors
17567        if (service != null && service.hasFileDescriptors() == true) {
17568            throw new IllegalArgumentException("File descriptors passed in Intent");
17569        }
17570
17571        synchronized(this) {
17572            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
17573        }
17574    }
17575
17576    @Override
17577    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
17578        enforceNotIsolatedCaller("peekService");
17579        // Refuse possible leaked file descriptors
17580        if (service != null && service.hasFileDescriptors() == true) {
17581            throw new IllegalArgumentException("File descriptors passed in Intent");
17582        }
17583
17584        if (callingPackage == null) {
17585            throw new IllegalArgumentException("callingPackage cannot be null");
17586        }
17587
17588        synchronized(this) {
17589            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
17590        }
17591    }
17592
17593    @Override
17594    public boolean stopServiceToken(ComponentName className, IBinder token,
17595            int startId) {
17596        synchronized(this) {
17597            return mServices.stopServiceTokenLocked(className, token, startId);
17598        }
17599    }
17600
17601    @Override
17602    public void setServiceForeground(ComponentName className, IBinder token,
17603            int id, Notification notification, int flags) {
17604        synchronized(this) {
17605            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
17606        }
17607    }
17608
17609    @Override
17610    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
17611            boolean requireFull, String name, String callerPackage) {
17612        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
17613                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
17614    }
17615
17616    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
17617            String className, int flags) {
17618        boolean result = false;
17619        // For apps that don't have pre-defined UIDs, check for permission
17620        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
17621            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17622                if (ActivityManager.checkUidPermission(
17623                        INTERACT_ACROSS_USERS,
17624                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
17625                    ComponentName comp = new ComponentName(aInfo.packageName, className);
17626                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
17627                            + " requests FLAG_SINGLE_USER, but app does not hold "
17628                            + INTERACT_ACROSS_USERS;
17629                    Slog.w(TAG, msg);
17630                    throw new SecurityException(msg);
17631                }
17632                // Permission passed
17633                result = true;
17634            }
17635        } else if ("system".equals(componentProcessName)) {
17636            result = true;
17637        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17638            // Phone app and persistent apps are allowed to export singleuser providers.
17639            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
17640                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
17641        }
17642        if (DEBUG_MU) Slog.v(TAG_MU,
17643                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
17644                + Integer.toHexString(flags) + ") = " + result);
17645        return result;
17646    }
17647
17648    /**
17649     * Checks to see if the caller is in the same app as the singleton
17650     * component, or the component is in a special app. It allows special apps
17651     * to export singleton components but prevents exporting singleton
17652     * components for regular apps.
17653     */
17654    boolean isValidSingletonCall(int callingUid, int componentUid) {
17655        int componentAppId = UserHandle.getAppId(componentUid);
17656        return UserHandle.isSameApp(callingUid, componentUid)
17657                || componentAppId == Process.SYSTEM_UID
17658                || componentAppId == Process.PHONE_UID
17659                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
17660                        == PackageManager.PERMISSION_GRANTED;
17661    }
17662
17663    public int bindService(IApplicationThread caller, IBinder token, Intent service,
17664            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
17665            int userId) throws TransactionTooLargeException {
17666        enforceNotIsolatedCaller("bindService");
17667
17668        // Refuse possible leaked file descriptors
17669        if (service != null && service.hasFileDescriptors() == true) {
17670            throw new IllegalArgumentException("File descriptors passed in Intent");
17671        }
17672
17673        if (callingPackage == null) {
17674            throw new IllegalArgumentException("callingPackage cannot be null");
17675        }
17676
17677        synchronized(this) {
17678            return mServices.bindServiceLocked(caller, token, service,
17679                    resolvedType, connection, flags, callingPackage, userId);
17680        }
17681    }
17682
17683    public boolean unbindService(IServiceConnection connection) {
17684        synchronized (this) {
17685            return mServices.unbindServiceLocked(connection);
17686        }
17687    }
17688
17689    public void publishService(IBinder token, Intent intent, IBinder service) {
17690        // Refuse possible leaked file descriptors
17691        if (intent != null && intent.hasFileDescriptors() == true) {
17692            throw new IllegalArgumentException("File descriptors passed in Intent");
17693        }
17694
17695        synchronized(this) {
17696            if (!(token instanceof ServiceRecord)) {
17697                throw new IllegalArgumentException("Invalid service token");
17698            }
17699            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17700        }
17701    }
17702
17703    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17704        // Refuse possible leaked file descriptors
17705        if (intent != null && intent.hasFileDescriptors() == true) {
17706            throw new IllegalArgumentException("File descriptors passed in Intent");
17707        }
17708
17709        synchronized(this) {
17710            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17711        }
17712    }
17713
17714    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17715        synchronized(this) {
17716            if (!(token instanceof ServiceRecord)) {
17717                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17718                throw new IllegalArgumentException("Invalid service token");
17719            }
17720            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17721        }
17722    }
17723
17724    // =========================================================
17725    // BACKUP AND RESTORE
17726    // =========================================================
17727
17728    // Cause the target app to be launched if necessary and its backup agent
17729    // instantiated.  The backup agent will invoke backupAgentCreated() on the
17730    // activity manager to announce its creation.
17731    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
17732        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
17733        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17734
17735        IPackageManager pm = AppGlobals.getPackageManager();
17736        ApplicationInfo app = null;
17737        try {
17738            app = pm.getApplicationInfo(packageName, 0, userId);
17739        } catch (RemoteException e) {
17740            // can't happen; package manager is process-local
17741        }
17742        if (app == null) {
17743            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
17744            return false;
17745        }
17746
17747        synchronized(this) {
17748            // !!! TODO: currently no check here that we're already bound
17749            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17750            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17751            synchronized (stats) {
17752                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17753            }
17754
17755            // Backup agent is now in use, its package can't be stopped.
17756            try {
17757                AppGlobals.getPackageManager().setPackageStoppedState(
17758                        app.packageName, false, UserHandle.getUserId(app.uid));
17759            } catch (RemoteException e) {
17760            } catch (IllegalArgumentException e) {
17761                Slog.w(TAG, "Failed trying to unstop package "
17762                        + app.packageName + ": " + e);
17763            }
17764
17765            BackupRecord r = new BackupRecord(ss, app, backupMode);
17766            ComponentName hostingName =
17767                    (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
17768                            ? new ComponentName(app.packageName, app.backupAgentName)
17769                            : new ComponentName("android", "FullBackupAgent");
17770            // startProcessLocked() returns existing proc's record if it's already running
17771            ProcessRecord proc = startProcessLocked(app.processName, app,
17772                    false, 0, "backup", hostingName, false, false, false);
17773            if (proc == null) {
17774                Slog.e(TAG, "Unable to start backup agent process " + r);
17775                return false;
17776            }
17777
17778            // If the app is a regular app (uid >= 10000) and not the system server or phone
17779            // process, etc, then mark it as being in full backup so that certain calls to the
17780            // process can be blocked. This is not reset to false anywhere because we kill the
17781            // process after the full backup is done and the ProcessRecord will vaporize anyway.
17782            if (UserHandle.isApp(app.uid) &&
17783                    backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
17784                proc.inFullBackup = true;
17785            }
17786            r.app = proc;
17787            mBackupTarget = r;
17788            mBackupAppName = app.packageName;
17789
17790            // Try not to kill the process during backup
17791            updateOomAdjLocked(proc);
17792
17793            // If the process is already attached, schedule the creation of the backup agent now.
17794            // If it is not yet live, this will be done when it attaches to the framework.
17795            if (proc.thread != null) {
17796                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17797                try {
17798                    proc.thread.scheduleCreateBackupAgent(app,
17799                            compatibilityInfoForPackageLocked(app), backupMode);
17800                } catch (RemoteException e) {
17801                    // Will time out on the backup manager side
17802                }
17803            } else {
17804                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17805            }
17806            // Invariants: at this point, the target app process exists and the application
17807            // is either already running or in the process of coming up.  mBackupTarget and
17808            // mBackupAppName describe the app, so that when it binds back to the AM we
17809            // know that it's scheduled for a backup-agent operation.
17810        }
17811
17812        return true;
17813    }
17814
17815    @Override
17816    public void clearPendingBackup() {
17817        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17818        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17819
17820        synchronized (this) {
17821            mBackupTarget = null;
17822            mBackupAppName = null;
17823        }
17824    }
17825
17826    // A backup agent has just come up
17827    public void backupAgentCreated(String agentPackageName, IBinder agent) {
17828        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17829                + " = " + agent);
17830
17831        synchronized(this) {
17832            if (!agentPackageName.equals(mBackupAppName)) {
17833                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17834                return;
17835            }
17836        }
17837
17838        long oldIdent = Binder.clearCallingIdentity();
17839        try {
17840            IBackupManager bm = IBackupManager.Stub.asInterface(
17841                    ServiceManager.getService(Context.BACKUP_SERVICE));
17842            bm.agentConnected(agentPackageName, agent);
17843        } catch (RemoteException e) {
17844            // can't happen; the backup manager service is local
17845        } catch (Exception e) {
17846            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17847            e.printStackTrace();
17848        } finally {
17849            Binder.restoreCallingIdentity(oldIdent);
17850        }
17851    }
17852
17853    // done with this agent
17854    public void unbindBackupAgent(ApplicationInfo appInfo) {
17855        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17856        if (appInfo == null) {
17857            Slog.w(TAG, "unbind backup agent for null app");
17858            return;
17859        }
17860
17861        synchronized(this) {
17862            try {
17863                if (mBackupAppName == null) {
17864                    Slog.w(TAG, "Unbinding backup agent with no active backup");
17865                    return;
17866                }
17867
17868                if (!mBackupAppName.equals(appInfo.packageName)) {
17869                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17870                    return;
17871                }
17872
17873                // Not backing this app up any more; reset its OOM adjustment
17874                final ProcessRecord proc = mBackupTarget.app;
17875                updateOomAdjLocked(proc);
17876                proc.inFullBackup = false;
17877
17878                // If the app crashed during backup, 'thread' will be null here
17879                if (proc.thread != null) {
17880                    try {
17881                        proc.thread.scheduleDestroyBackupAgent(appInfo,
17882                                compatibilityInfoForPackageLocked(appInfo));
17883                    } catch (Exception e) {
17884                        Slog.e(TAG, "Exception when unbinding backup agent:");
17885                        e.printStackTrace();
17886                    }
17887                }
17888            } finally {
17889                mBackupTarget = null;
17890                mBackupAppName = null;
17891            }
17892        }
17893    }
17894    // =========================================================
17895    // BROADCASTS
17896    // =========================================================
17897
17898    boolean isPendingBroadcastProcessLocked(int pid) {
17899        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17900                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17901    }
17902
17903    void skipPendingBroadcastLocked(int pid) {
17904            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17905            for (BroadcastQueue queue : mBroadcastQueues) {
17906                queue.skipPendingBroadcastLocked(pid);
17907            }
17908    }
17909
17910    // The app just attached; send any pending broadcasts that it should receive
17911    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17912        boolean didSomething = false;
17913        for (BroadcastQueue queue : mBroadcastQueues) {
17914            didSomething |= queue.sendPendingBroadcastsLocked(app);
17915        }
17916        return didSomething;
17917    }
17918
17919    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17920            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17921        enforceNotIsolatedCaller("registerReceiver");
17922        ArrayList<Intent> stickyIntents = null;
17923        ProcessRecord callerApp = null;
17924        int callingUid;
17925        int callingPid;
17926        synchronized(this) {
17927            if (caller != null) {
17928                callerApp = getRecordForAppLocked(caller);
17929                if (callerApp == null) {
17930                    throw new SecurityException(
17931                            "Unable to find app for caller " + caller
17932                            + " (pid=" + Binder.getCallingPid()
17933                            + ") when registering receiver " + receiver);
17934                }
17935                if (callerApp.info.uid != Process.SYSTEM_UID &&
17936                        !callerApp.pkgList.containsKey(callerPackage) &&
17937                        !"android".equals(callerPackage)) {
17938                    throw new SecurityException("Given caller package " + callerPackage
17939                            + " is not running in process " + callerApp);
17940                }
17941                callingUid = callerApp.info.uid;
17942                callingPid = callerApp.pid;
17943            } else {
17944                callerPackage = null;
17945                callingUid = Binder.getCallingUid();
17946                callingPid = Binder.getCallingPid();
17947            }
17948
17949            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17950                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17951
17952            Iterator<String> actions = filter.actionsIterator();
17953            if (actions == null) {
17954                ArrayList<String> noAction = new ArrayList<String>(1);
17955                noAction.add(null);
17956                actions = noAction.iterator();
17957            }
17958
17959            // Collect stickies of users
17960            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17961            while (actions.hasNext()) {
17962                String action = actions.next();
17963                for (int id : userIds) {
17964                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17965                    if (stickies != null) {
17966                        ArrayList<Intent> intents = stickies.get(action);
17967                        if (intents != null) {
17968                            if (stickyIntents == null) {
17969                                stickyIntents = new ArrayList<Intent>();
17970                            }
17971                            stickyIntents.addAll(intents);
17972                        }
17973                    }
17974                }
17975            }
17976        }
17977
17978        ArrayList<Intent> allSticky = null;
17979        if (stickyIntents != null) {
17980            final ContentResolver resolver = mContext.getContentResolver();
17981            // Look for any matching sticky broadcasts...
17982            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17983                Intent intent = stickyIntents.get(i);
17984                // If intent has scheme "content", it will need to acccess
17985                // provider that needs to lock mProviderMap in ActivityThread
17986                // and also it may need to wait application response, so we
17987                // cannot lock ActivityManagerService here.
17988                if (filter.match(resolver, intent, true, TAG) >= 0) {
17989                    if (allSticky == null) {
17990                        allSticky = new ArrayList<Intent>();
17991                    }
17992                    allSticky.add(intent);
17993                }
17994            }
17995        }
17996
17997        // The first sticky in the list is returned directly back to the client.
17998        Intent sticky = allSticky != null ? allSticky.get(0) : null;
17999        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
18000        if (receiver == null) {
18001            return sticky;
18002        }
18003
18004        synchronized (this) {
18005            if (callerApp != null && (callerApp.thread == null
18006                    || callerApp.thread.asBinder() != caller.asBinder())) {
18007                // Original caller already died
18008                return null;
18009            }
18010            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18011            if (rl == null) {
18012                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
18013                        userId, receiver);
18014                if (rl.app != null) {
18015                    rl.app.receivers.add(rl);
18016                } else {
18017                    try {
18018                        receiver.asBinder().linkToDeath(rl, 0);
18019                    } catch (RemoteException e) {
18020                        return sticky;
18021                    }
18022                    rl.linkedToDeath = true;
18023                }
18024                mRegisteredReceivers.put(receiver.asBinder(), rl);
18025            } else if (rl.uid != callingUid) {
18026                throw new IllegalArgumentException(
18027                        "Receiver requested to register for uid " + callingUid
18028                        + " was previously registered for uid " + rl.uid);
18029            } else if (rl.pid != callingPid) {
18030                throw new IllegalArgumentException(
18031                        "Receiver requested to register for pid " + callingPid
18032                        + " was previously registered for pid " + rl.pid);
18033            } else if (rl.userId != userId) {
18034                throw new IllegalArgumentException(
18035                        "Receiver requested to register for user " + userId
18036                        + " was previously registered for user " + rl.userId);
18037            }
18038            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
18039                    permission, callingUid, userId);
18040            rl.add(bf);
18041            if (!bf.debugCheck()) {
18042                Slog.w(TAG, "==> For Dynamic broadcast");
18043            }
18044            mReceiverResolver.addFilter(bf);
18045
18046            // Enqueue broadcasts for all existing stickies that match
18047            // this filter.
18048            if (allSticky != null) {
18049                ArrayList receivers = new ArrayList();
18050                receivers.add(bf);
18051
18052                final int stickyCount = allSticky.size();
18053                for (int i = 0; i < stickyCount; i++) {
18054                    Intent intent = allSticky.get(i);
18055                    BroadcastQueue queue = broadcastQueueForIntent(intent);
18056                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
18057                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
18058                            null, 0, null, null, false, true, true, -1);
18059                    queue.enqueueParallelBroadcastLocked(r);
18060                    queue.scheduleBroadcastsLocked();
18061                }
18062            }
18063
18064            return sticky;
18065        }
18066    }
18067
18068    public void unregisterReceiver(IIntentReceiver receiver) {
18069        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
18070
18071        final long origId = Binder.clearCallingIdentity();
18072        try {
18073            boolean doTrim = false;
18074
18075            synchronized(this) {
18076                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18077                if (rl != null) {
18078                    final BroadcastRecord r = rl.curBroadcast;
18079                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
18080                        final boolean doNext = r.queue.finishReceiverLocked(
18081                                r, r.resultCode, r.resultData, r.resultExtras,
18082                                r.resultAbort, false);
18083                        if (doNext) {
18084                            doTrim = true;
18085                            r.queue.processNextBroadcast(false);
18086                        }
18087                    }
18088
18089                    if (rl.app != null) {
18090                        rl.app.receivers.remove(rl);
18091                    }
18092                    removeReceiverLocked(rl);
18093                    if (rl.linkedToDeath) {
18094                        rl.linkedToDeath = false;
18095                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
18096                    }
18097                }
18098            }
18099
18100            // If we actually concluded any broadcasts, we might now be able
18101            // to trim the recipients' apps from our working set
18102            if (doTrim) {
18103                trimApplications();
18104                return;
18105            }
18106
18107        } finally {
18108            Binder.restoreCallingIdentity(origId);
18109        }
18110    }
18111
18112    void removeReceiverLocked(ReceiverList rl) {
18113        mRegisteredReceivers.remove(rl.receiver.asBinder());
18114        for (int i = rl.size() - 1; i >= 0; i--) {
18115            mReceiverResolver.removeFilter(rl.get(i));
18116        }
18117    }
18118
18119    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
18120        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18121            ProcessRecord r = mLruProcesses.get(i);
18122            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
18123                try {
18124                    r.thread.dispatchPackageBroadcast(cmd, packages);
18125                } catch (RemoteException ex) {
18126                }
18127            }
18128        }
18129    }
18130
18131    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
18132            int callingUid, int[] users) {
18133        // TODO: come back and remove this assumption to triage all broadcasts
18134        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
18135
18136        List<ResolveInfo> receivers = null;
18137        try {
18138            HashSet<ComponentName> singleUserReceivers = null;
18139            boolean scannedFirstReceivers = false;
18140            for (int user : users) {
18141                // Skip users that have Shell restrictions, with exception of always permitted
18142                // Shell broadcasts
18143                if (callingUid == Process.SHELL_UID
18144                        && mUserController.hasUserRestriction(
18145                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
18146                        && !isPermittedShellBroadcast(intent)) {
18147                    continue;
18148                }
18149                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
18150                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
18151                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
18152                    // If this is not the system user, we need to check for
18153                    // any receivers that should be filtered out.
18154                    for (int i=0; i<newReceivers.size(); i++) {
18155                        ResolveInfo ri = newReceivers.get(i);
18156                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
18157                            newReceivers.remove(i);
18158                            i--;
18159                        }
18160                    }
18161                }
18162                if (newReceivers != null && newReceivers.size() == 0) {
18163                    newReceivers = null;
18164                }
18165                if (receivers == null) {
18166                    receivers = newReceivers;
18167                } else if (newReceivers != null) {
18168                    // We need to concatenate the additional receivers
18169                    // found with what we have do far.  This would be easy,
18170                    // but we also need to de-dup any receivers that are
18171                    // singleUser.
18172                    if (!scannedFirstReceivers) {
18173                        // Collect any single user receivers we had already retrieved.
18174                        scannedFirstReceivers = true;
18175                        for (int i=0; i<receivers.size(); i++) {
18176                            ResolveInfo ri = receivers.get(i);
18177                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18178                                ComponentName cn = new ComponentName(
18179                                        ri.activityInfo.packageName, ri.activityInfo.name);
18180                                if (singleUserReceivers == null) {
18181                                    singleUserReceivers = new HashSet<ComponentName>();
18182                                }
18183                                singleUserReceivers.add(cn);
18184                            }
18185                        }
18186                    }
18187                    // Add the new results to the existing results, tracking
18188                    // and de-dupping single user receivers.
18189                    for (int i=0; i<newReceivers.size(); i++) {
18190                        ResolveInfo ri = newReceivers.get(i);
18191                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18192                            ComponentName cn = new ComponentName(
18193                                    ri.activityInfo.packageName, ri.activityInfo.name);
18194                            if (singleUserReceivers == null) {
18195                                singleUserReceivers = new HashSet<ComponentName>();
18196                            }
18197                            if (!singleUserReceivers.contains(cn)) {
18198                                singleUserReceivers.add(cn);
18199                                receivers.add(ri);
18200                            }
18201                        } else {
18202                            receivers.add(ri);
18203                        }
18204                    }
18205                }
18206            }
18207        } catch (RemoteException ex) {
18208            // pm is in same process, this will never happen.
18209        }
18210        return receivers;
18211    }
18212
18213    private boolean isPermittedShellBroadcast(Intent intent) {
18214        // remote bugreport should always be allowed to be taken
18215        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
18216    }
18217
18218    private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
18219            String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
18220        if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
18221            // Don't yell about broadcasts sent via shell
18222            return;
18223        }
18224
18225        final String action = intent.getAction();
18226        if (isProtectedBroadcast
18227                || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
18228                || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
18229                || Intent.ACTION_MEDIA_BUTTON.equals(action)
18230                || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
18231                || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
18232                || Intent.ACTION_MASTER_CLEAR.equals(action)
18233                || Intent.ACTION_FACTORY_RESET.equals(action)
18234                || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
18235                || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
18236                || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
18237                || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
18238                || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
18239                || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
18240                || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) {
18241            // Broadcast is either protected, or it's a public action that
18242            // we've relaxed, so it's fine for system internals to send.
18243            return;
18244        }
18245
18246        // This broadcast may be a problem...  but there are often system components that
18247        // want to send an internal broadcast to themselves, which is annoying to have to
18248        // explicitly list each action as a protected broadcast, so we will check for that
18249        // one safe case and allow it: an explicit broadcast, only being received by something
18250        // that has protected itself.
18251        if (receivers != null && receivers.size() > 0
18252                && (intent.getPackage() != null || intent.getComponent() != null)) {
18253            boolean allProtected = true;
18254            for (int i = receivers.size()-1; i >= 0; i--) {
18255                Object target = receivers.get(i);
18256                if (target instanceof ResolveInfo) {
18257                    ResolveInfo ri = (ResolveInfo)target;
18258                    if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
18259                        allProtected = false;
18260                        break;
18261                    }
18262                } else {
18263                    BroadcastFilter bf = (BroadcastFilter)target;
18264                    if (bf.requiredPermission == null) {
18265                        allProtected = false;
18266                        break;
18267                    }
18268                }
18269            }
18270            if (allProtected) {
18271                // All safe!
18272                return;
18273            }
18274        }
18275
18276        // The vast majority of broadcasts sent from system internals
18277        // should be protected to avoid security holes, so yell loudly
18278        // to ensure we examine these cases.
18279        if (callerApp != null) {
18280            Log.wtf(TAG, "Sending non-protected broadcast " + action
18281                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
18282                    new Throwable());
18283        } else {
18284            Log.wtf(TAG, "Sending non-protected broadcast " + action
18285                            + " from system uid " + UserHandle.formatUid(callingUid)
18286                            + " pkg " + callerPackage,
18287                    new Throwable());
18288        }
18289    }
18290
18291    final int broadcastIntentLocked(ProcessRecord callerApp,
18292            String callerPackage, Intent intent, String resolvedType,
18293            IIntentReceiver resultTo, int resultCode, String resultData,
18294            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
18295            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
18296        intent = new Intent(intent);
18297
18298        // By default broadcasts do not go to stopped apps.
18299        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
18300
18301        // If we have not finished booting, don't allow this to launch new processes.
18302        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
18303            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18304        }
18305
18306        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
18307                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
18308                + " ordered=" + ordered + " userid=" + userId);
18309        if ((resultTo != null) && !ordered) {
18310            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
18311        }
18312
18313        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
18314                ALLOW_NON_FULL, "broadcast", callerPackage);
18315
18316        // Make sure that the user who is receiving this broadcast is running.
18317        // If not, we will just skip it. Make an exception for shutdown broadcasts
18318        // and upgrade steps.
18319
18320        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
18321            if ((callingUid != Process.SYSTEM_UID
18322                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
18323                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
18324                Slog.w(TAG, "Skipping broadcast of " + intent
18325                        + ": user " + userId + " is stopped");
18326                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
18327            }
18328        }
18329
18330        BroadcastOptions brOptions = null;
18331        if (bOptions != null) {
18332            brOptions = new BroadcastOptions(bOptions);
18333            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
18334                // See if the caller is allowed to do this.  Note we are checking against
18335                // the actual real caller (not whoever provided the operation as say a
18336                // PendingIntent), because that who is actually supplied the arguments.
18337                if (checkComponentPermission(
18338                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
18339                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
18340                        != PackageManager.PERMISSION_GRANTED) {
18341                    String msg = "Permission Denial: " + intent.getAction()
18342                            + " broadcast from " + callerPackage + " (pid=" + callingPid
18343                            + ", uid=" + callingUid + ")"
18344                            + " requires "
18345                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
18346                    Slog.w(TAG, msg);
18347                    throw new SecurityException(msg);
18348                }
18349            }
18350        }
18351
18352        // Verify that protected broadcasts are only being sent by system code,
18353        // and that system code is only sending protected broadcasts.
18354        final String action = intent.getAction();
18355        final boolean isProtectedBroadcast;
18356        try {
18357            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
18358        } catch (RemoteException e) {
18359            Slog.w(TAG, "Remote exception", e);
18360            return ActivityManager.BROADCAST_SUCCESS;
18361        }
18362
18363        final boolean isCallerSystem;
18364        switch (UserHandle.getAppId(callingUid)) {
18365            case Process.ROOT_UID:
18366            case Process.SYSTEM_UID:
18367            case Process.PHONE_UID:
18368            case Process.BLUETOOTH_UID:
18369            case Process.NFC_UID:
18370                isCallerSystem = true;
18371                break;
18372            default:
18373                isCallerSystem = (callerApp != null) && callerApp.persistent;
18374                break;
18375        }
18376
18377        // First line security check before anything else: stop non-system apps from
18378        // sending protected broadcasts.
18379        if (!isCallerSystem) {
18380            if (isProtectedBroadcast) {
18381                String msg = "Permission Denial: not allowed to send broadcast "
18382                        + action + " from pid="
18383                        + callingPid + ", uid=" + callingUid;
18384                Slog.w(TAG, msg);
18385                throw new SecurityException(msg);
18386
18387            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
18388                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
18389                // Special case for compatibility: we don't want apps to send this,
18390                // but historically it has not been protected and apps may be using it
18391                // to poke their own app widget.  So, instead of making it protected,
18392                // just limit it to the caller.
18393                if (callerPackage == null) {
18394                    String msg = "Permission Denial: not allowed to send broadcast "
18395                            + action + " from unknown caller.";
18396                    Slog.w(TAG, msg);
18397                    throw new SecurityException(msg);
18398                } else if (intent.getComponent() != null) {
18399                    // They are good enough to send to an explicit component...  verify
18400                    // it is being sent to the calling app.
18401                    if (!intent.getComponent().getPackageName().equals(
18402                            callerPackage)) {
18403                        String msg = "Permission Denial: not allowed to send broadcast "
18404                                + action + " to "
18405                                + intent.getComponent().getPackageName() + " from "
18406                                + callerPackage;
18407                        Slog.w(TAG, msg);
18408                        throw new SecurityException(msg);
18409                    }
18410                } else {
18411                    // Limit broadcast to their own package.
18412                    intent.setPackage(callerPackage);
18413                }
18414            }
18415        }
18416
18417        if (action != null) {
18418            if (getBackgroundLaunchBroadcasts().contains(action)) {
18419                if (DEBUG_BACKGROUND_CHECK) {
18420                    Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
18421                }
18422                intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
18423            }
18424
18425            switch (action) {
18426                case Intent.ACTION_UID_REMOVED:
18427                case Intent.ACTION_PACKAGE_REMOVED:
18428                case Intent.ACTION_PACKAGE_CHANGED:
18429                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18430                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18431                case Intent.ACTION_PACKAGES_SUSPENDED:
18432                case Intent.ACTION_PACKAGES_UNSUSPENDED:
18433                    // Handle special intents: if this broadcast is from the package
18434                    // manager about a package being removed, we need to remove all of
18435                    // its activities from the history stack.
18436                    if (checkComponentPermission(
18437                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
18438                            callingPid, callingUid, -1, true)
18439                            != PackageManager.PERMISSION_GRANTED) {
18440                        String msg = "Permission Denial: " + intent.getAction()
18441                                + " broadcast from " + callerPackage + " (pid=" + callingPid
18442                                + ", uid=" + callingUid + ")"
18443                                + " requires "
18444                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
18445                        Slog.w(TAG, msg);
18446                        throw new SecurityException(msg);
18447                    }
18448                    switch (action) {
18449                        case Intent.ACTION_UID_REMOVED:
18450                            final Bundle intentExtras = intent.getExtras();
18451                            final int uid = intentExtras != null
18452                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
18453                            if (uid >= 0) {
18454                                mBatteryStatsService.removeUid(uid);
18455                                mAppOpsService.uidRemoved(uid);
18456                            }
18457                            break;
18458                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18459                            // If resources are unavailable just force stop all those packages
18460                            // and flush the attribute cache as well.
18461                            String list[] =
18462                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18463                            if (list != null && list.length > 0) {
18464                                for (int i = 0; i < list.length; i++) {
18465                                    forceStopPackageLocked(list[i], -1, false, true, true,
18466                                            false, false, userId, "storage unmount");
18467                                }
18468                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18469                                sendPackageBroadcastLocked(
18470                                        ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
18471                                        list, userId);
18472                            }
18473                            break;
18474                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18475                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18476                            break;
18477                        case Intent.ACTION_PACKAGE_REMOVED:
18478                        case Intent.ACTION_PACKAGE_CHANGED:
18479                            Uri data = intent.getData();
18480                            String ssp;
18481                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
18482                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
18483                                final boolean replacing =
18484                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18485                                final boolean killProcess =
18486                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
18487                                final boolean fullUninstall = removed && !replacing;
18488                                if (removed) {
18489                                    if (killProcess) {
18490                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
18491                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
18492                                                false, true, true, false, fullUninstall, userId,
18493                                                removed ? "pkg removed" : "pkg changed");
18494                                    }
18495                                    final int cmd = killProcess
18496                                            ? ApplicationThreadConstants.PACKAGE_REMOVED
18497                                            : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
18498                                    sendPackageBroadcastLocked(cmd,
18499                                            new String[] {ssp}, userId);
18500                                    if (fullUninstall) {
18501                                        mAppOpsService.packageRemoved(
18502                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
18503
18504                                        // Remove all permissions granted from/to this package
18505                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
18506
18507                                        removeTasksByPackageNameLocked(ssp, userId);
18508
18509                                        // Hide the "unsupported display" dialog if necessary.
18510                                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18511                                                mUnsupportedDisplaySizeDialog.getPackageName())) {
18512                                            mUnsupportedDisplaySizeDialog.dismiss();
18513                                            mUnsupportedDisplaySizeDialog = null;
18514                                        }
18515                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
18516                                        mBatteryStatsService.notePackageUninstalled(ssp);
18517                                    }
18518                                } else {
18519                                    if (killProcess) {
18520                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
18521                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
18522                                                userId, ProcessList.INVALID_ADJ,
18523                                                false, true, true, false, "change " + ssp);
18524                                    }
18525                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
18526                                            intent.getStringArrayExtra(
18527                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
18528                                }
18529                            }
18530                            break;
18531                        case Intent.ACTION_PACKAGES_SUSPENDED:
18532                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
18533                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
18534                                    intent.getAction());
18535                            final String[] packageNames = intent.getStringArrayExtra(
18536                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
18537                            final int userHandle = intent.getIntExtra(
18538                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
18539
18540                            synchronized(ActivityManagerService.this) {
18541                                mRecentTasks.onPackagesSuspendedChanged(
18542                                        packageNames, suspended, userHandle);
18543                            }
18544                            break;
18545                    }
18546                    break;
18547                case Intent.ACTION_PACKAGE_REPLACED:
18548                {
18549                    final Uri data = intent.getData();
18550                    final String ssp;
18551                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18552                        final ApplicationInfo aInfo =
18553                                getPackageManagerInternalLocked().getApplicationInfo(
18554                                        ssp,
18555                                        userId);
18556                        if (aInfo == null) {
18557                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
18558                                    + " ssp=" + ssp + " data=" + data);
18559                            return ActivityManager.BROADCAST_SUCCESS;
18560                        }
18561                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
18562                        sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
18563                                new String[] {ssp}, userId);
18564                    }
18565                    break;
18566                }
18567                case Intent.ACTION_PACKAGE_ADDED:
18568                {
18569                    // Special case for adding a package: by default turn on compatibility mode.
18570                    Uri data = intent.getData();
18571                    String ssp;
18572                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18573                        final boolean replacing =
18574                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18575                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
18576
18577                        try {
18578                            ApplicationInfo ai = AppGlobals.getPackageManager().
18579                                    getApplicationInfo(ssp, 0, 0);
18580                            mBatteryStatsService.notePackageInstalled(ssp,
18581                                    ai != null ? ai.versionCode : 0);
18582                        } catch (RemoteException e) {
18583                        }
18584                    }
18585                    break;
18586                }
18587                case Intent.ACTION_PACKAGE_DATA_CLEARED:
18588                {
18589                    Uri data = intent.getData();
18590                    String ssp;
18591                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18592                        // Hide the "unsupported display" dialog if necessary.
18593                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18594                                mUnsupportedDisplaySizeDialog.getPackageName())) {
18595                            mUnsupportedDisplaySizeDialog.dismiss();
18596                            mUnsupportedDisplaySizeDialog = null;
18597                        }
18598                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
18599                    }
18600                    break;
18601                }
18602                case Intent.ACTION_TIMEZONE_CHANGED:
18603                    // If this is the time zone changed action, queue up a message that will reset
18604                    // the timezone of all currently running processes. This message will get
18605                    // queued up before the broadcast happens.
18606                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
18607                    break;
18608                case Intent.ACTION_TIME_CHANGED:
18609                    // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
18610                    // the tri-state value it may contain and "unknown".
18611                    // For convenience we re-use the Intent extra values.
18612                    final int NO_EXTRA_VALUE_FOUND = -1;
18613                    final int timeFormatPreferenceMsgValue = intent.getIntExtra(
18614                            Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
18615                            NO_EXTRA_VALUE_FOUND /* defaultValue */);
18616                    // Only send a message if the time preference is available.
18617                    if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
18618                        Message updateTimePreferenceMsg =
18619                                mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
18620                                        timeFormatPreferenceMsgValue, 0);
18621                        mHandler.sendMessage(updateTimePreferenceMsg);
18622                    }
18623                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18624                    synchronized (stats) {
18625                        stats.noteCurrentTimeChangedLocked();
18626                    }
18627                    break;
18628                case Intent.ACTION_CLEAR_DNS_CACHE:
18629                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
18630                    break;
18631                case Proxy.PROXY_CHANGE_ACTION:
18632                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
18633                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
18634                    break;
18635                case android.hardware.Camera.ACTION_NEW_PICTURE:
18636                case android.hardware.Camera.ACTION_NEW_VIDEO:
18637                    // These broadcasts are no longer allowed by the system, since they can
18638                    // cause significant thrashing at a crictical point (using the camera).
18639                    // Apps should use JobScehduler to monitor for media provider changes.
18640                    Slog.w(TAG, action + " no longer allowed; dropping from "
18641                            + UserHandle.formatUid(callingUid));
18642                    if (resultTo != null) {
18643                        final BroadcastQueue queue = broadcastQueueForIntent(intent);
18644                        try {
18645                            queue.performReceiveLocked(callerApp, resultTo, intent,
18646                                    Activity.RESULT_CANCELED, null, null,
18647                                    false, false, userId);
18648                        } catch (RemoteException e) {
18649                            Slog.w(TAG, "Failure ["
18650                                    + queue.mQueueName + "] sending broadcast result of "
18651                                    + intent, e);
18652
18653                        }
18654                    }
18655                    // Lie; we don't want to crash the app.
18656                    return ActivityManager.BROADCAST_SUCCESS;
18657                case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
18658                    mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
18659                    break;
18660            }
18661        }
18662
18663        // Add to the sticky list if requested.
18664        if (sticky) {
18665            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
18666                    callingPid, callingUid)
18667                    != PackageManager.PERMISSION_GRANTED) {
18668                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
18669                        + callingPid + ", uid=" + callingUid
18670                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18671                Slog.w(TAG, msg);
18672                throw new SecurityException(msg);
18673            }
18674            if (requiredPermissions != null && requiredPermissions.length > 0) {
18675                Slog.w(TAG, "Can't broadcast sticky intent " + intent
18676                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
18677                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
18678            }
18679            if (intent.getComponent() != null) {
18680                throw new SecurityException(
18681                        "Sticky broadcasts can't target a specific component");
18682            }
18683            // We use userId directly here, since the "all" target is maintained
18684            // as a separate set of sticky broadcasts.
18685            if (userId != UserHandle.USER_ALL) {
18686                // But first, if this is not a broadcast to all users, then
18687                // make sure it doesn't conflict with an existing broadcast to
18688                // all users.
18689                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
18690                        UserHandle.USER_ALL);
18691                if (stickies != null) {
18692                    ArrayList<Intent> list = stickies.get(intent.getAction());
18693                    if (list != null) {
18694                        int N = list.size();
18695                        int i;
18696                        for (i=0; i<N; i++) {
18697                            if (intent.filterEquals(list.get(i))) {
18698                                throw new IllegalArgumentException(
18699                                        "Sticky broadcast " + intent + " for user "
18700                                        + userId + " conflicts with existing global broadcast");
18701                            }
18702                        }
18703                    }
18704                }
18705            }
18706            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18707            if (stickies == null) {
18708                stickies = new ArrayMap<>();
18709                mStickyBroadcasts.put(userId, stickies);
18710            }
18711            ArrayList<Intent> list = stickies.get(intent.getAction());
18712            if (list == null) {
18713                list = new ArrayList<>();
18714                stickies.put(intent.getAction(), list);
18715            }
18716            final int stickiesCount = list.size();
18717            int i;
18718            for (i = 0; i < stickiesCount; i++) {
18719                if (intent.filterEquals(list.get(i))) {
18720                    // This sticky already exists, replace it.
18721                    list.set(i, new Intent(intent));
18722                    break;
18723                }
18724            }
18725            if (i >= stickiesCount) {
18726                list.add(new Intent(intent));
18727            }
18728        }
18729
18730        int[] users;
18731        if (userId == UserHandle.USER_ALL) {
18732            // Caller wants broadcast to go to all started users.
18733            users = mUserController.getStartedUserArrayLocked();
18734        } else {
18735            // Caller wants broadcast to go to one specific user.
18736            users = new int[] {userId};
18737        }
18738
18739        // Figure out who all will receive this broadcast.
18740        List receivers = null;
18741        List<BroadcastFilter> registeredReceivers = null;
18742        // Need to resolve the intent to interested receivers...
18743        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
18744                 == 0) {
18745            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
18746        }
18747        if (intent.getComponent() == null) {
18748            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
18749                // Query one target user at a time, excluding shell-restricted users
18750                for (int i = 0; i < users.length; i++) {
18751                    if (mUserController.hasUserRestriction(
18752                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
18753                        continue;
18754                    }
18755                    List<BroadcastFilter> registeredReceiversForUser =
18756                            mReceiverResolver.queryIntent(intent,
18757                                    resolvedType, false /*defaultOnly*/, users[i]);
18758                    if (registeredReceivers == null) {
18759                        registeredReceivers = registeredReceiversForUser;
18760                    } else if (registeredReceiversForUser != null) {
18761                        registeredReceivers.addAll(registeredReceiversForUser);
18762                    }
18763                }
18764            } else {
18765                registeredReceivers = mReceiverResolver.queryIntent(intent,
18766                        resolvedType, false /*defaultOnly*/, userId);
18767            }
18768        }
18769
18770        final boolean replacePending =
18771                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
18772
18773        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
18774                + " replacePending=" + replacePending);
18775
18776        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
18777        if (!ordered && NR > 0) {
18778            // If we are not serializing this broadcast, then send the
18779            // registered receivers separately so they don't wait for the
18780            // components to be launched.
18781            if (isCallerSystem) {
18782                checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18783                        isProtectedBroadcast, registeredReceivers);
18784            }
18785            final BroadcastQueue queue = broadcastQueueForIntent(intent);
18786            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18787                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
18788                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
18789                    resultExtras, ordered, sticky, false, userId);
18790            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
18791            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
18792            if (!replaced) {
18793                queue.enqueueParallelBroadcastLocked(r);
18794                queue.scheduleBroadcastsLocked();
18795            }
18796            registeredReceivers = null;
18797            NR = 0;
18798        }
18799
18800        // Merge into one list.
18801        int ir = 0;
18802        if (receivers != null) {
18803            // A special case for PACKAGE_ADDED: do not allow the package
18804            // being added to see this broadcast.  This prevents them from
18805            // using this as a back door to get run as soon as they are
18806            // installed.  Maybe in the future we want to have a special install
18807            // broadcast or such for apps, but we'd like to deliberately make
18808            // this decision.
18809            String skipPackages[] = null;
18810            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
18811                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
18812                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
18813                Uri data = intent.getData();
18814                if (data != null) {
18815                    String pkgName = data.getSchemeSpecificPart();
18816                    if (pkgName != null) {
18817                        skipPackages = new String[] { pkgName };
18818                    }
18819                }
18820            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18821                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18822            }
18823            if (skipPackages != null && (skipPackages.length > 0)) {
18824                for (String skipPackage : skipPackages) {
18825                    if (skipPackage != null) {
18826                        int NT = receivers.size();
18827                        for (int it=0; it<NT; it++) {
18828                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
18829                            if (curt.activityInfo.packageName.equals(skipPackage)) {
18830                                receivers.remove(it);
18831                                it--;
18832                                NT--;
18833                            }
18834                        }
18835                    }
18836                }
18837            }
18838
18839            int NT = receivers != null ? receivers.size() : 0;
18840            int it = 0;
18841            ResolveInfo curt = null;
18842            BroadcastFilter curr = null;
18843            while (it < NT && ir < NR) {
18844                if (curt == null) {
18845                    curt = (ResolveInfo)receivers.get(it);
18846                }
18847                if (curr == null) {
18848                    curr = registeredReceivers.get(ir);
18849                }
18850                if (curr.getPriority() >= curt.priority) {
18851                    // Insert this broadcast record into the final list.
18852                    receivers.add(it, curr);
18853                    ir++;
18854                    curr = null;
18855                    it++;
18856                    NT++;
18857                } else {
18858                    // Skip to the next ResolveInfo in the final list.
18859                    it++;
18860                    curt = null;
18861                }
18862            }
18863        }
18864        while (ir < NR) {
18865            if (receivers == null) {
18866                receivers = new ArrayList();
18867            }
18868            receivers.add(registeredReceivers.get(ir));
18869            ir++;
18870        }
18871
18872        if (isCallerSystem) {
18873            checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18874                    isProtectedBroadcast, receivers);
18875        }
18876
18877        if ((receivers != null && receivers.size() > 0)
18878                || resultTo != null) {
18879            BroadcastQueue queue = broadcastQueueForIntent(intent);
18880            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18881                    callerPackage, callingPid, callingUid, resolvedType,
18882                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18883                    resultData, resultExtras, ordered, sticky, false, userId);
18884
18885            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18886                    + ": prev had " + queue.mOrderedBroadcasts.size());
18887            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18888                    "Enqueueing broadcast " + r.intent.getAction());
18889
18890            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18891            if (!replaced) {
18892                queue.enqueueOrderedBroadcastLocked(r);
18893                queue.scheduleBroadcastsLocked();
18894            }
18895        } else {
18896            // There was nobody interested in the broadcast, but we still want to record
18897            // that it happened.
18898            if (intent.getComponent() == null && intent.getPackage() == null
18899                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18900                // This was an implicit broadcast... let's record it for posterity.
18901                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18902            }
18903        }
18904
18905        return ActivityManager.BROADCAST_SUCCESS;
18906    }
18907
18908    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18909            int skipCount, long dispatchTime) {
18910        final long now = SystemClock.elapsedRealtime();
18911        if (mCurBroadcastStats == null ||
18912                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18913            mLastBroadcastStats = mCurBroadcastStats;
18914            if (mLastBroadcastStats != null) {
18915                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18916                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18917            }
18918            mCurBroadcastStats = new BroadcastStats();
18919        }
18920        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18921    }
18922
18923    final Intent verifyBroadcastLocked(Intent intent) {
18924        // Refuse possible leaked file descriptors
18925        if (intent != null && intent.hasFileDescriptors() == true) {
18926            throw new IllegalArgumentException("File descriptors passed in Intent");
18927        }
18928
18929        int flags = intent.getFlags();
18930
18931        if (!mProcessesReady) {
18932            // if the caller really truly claims to know what they're doing, go
18933            // ahead and allow the broadcast without launching any receivers
18934            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18935                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18936            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18937                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18938                        + " before boot completion");
18939                throw new IllegalStateException("Cannot broadcast before boot completed");
18940            }
18941        }
18942
18943        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18944            throw new IllegalArgumentException(
18945                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18946        }
18947
18948        if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
18949            switch (Binder.getCallingUid()) {
18950                case Process.ROOT_UID:
18951                case Process.SHELL_UID:
18952                    break;
18953                default:
18954                    Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
18955                            + Binder.getCallingUid());
18956                    intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
18957                    break;
18958            }
18959        }
18960
18961        return intent;
18962    }
18963
18964    public final int broadcastIntent(IApplicationThread caller,
18965            Intent intent, String resolvedType, IIntentReceiver resultTo,
18966            int resultCode, String resultData, Bundle resultExtras,
18967            String[] requiredPermissions, int appOp, Bundle bOptions,
18968            boolean serialized, boolean sticky, int userId) {
18969        enforceNotIsolatedCaller("broadcastIntent");
18970        synchronized(this) {
18971            intent = verifyBroadcastLocked(intent);
18972
18973            final ProcessRecord callerApp = getRecordForAppLocked(caller);
18974            final int callingPid = Binder.getCallingPid();
18975            final int callingUid = Binder.getCallingUid();
18976            final long origId = Binder.clearCallingIdentity();
18977            int res = broadcastIntentLocked(callerApp,
18978                    callerApp != null ? callerApp.info.packageName : null,
18979                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18980                    requiredPermissions, appOp, bOptions, serialized, sticky,
18981                    callingPid, callingUid, userId);
18982            Binder.restoreCallingIdentity(origId);
18983            return res;
18984        }
18985    }
18986
18987
18988    int broadcastIntentInPackage(String packageName, int uid,
18989            Intent intent, String resolvedType, IIntentReceiver resultTo,
18990            int resultCode, String resultData, Bundle resultExtras,
18991            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18992            int userId) {
18993        synchronized(this) {
18994            intent = verifyBroadcastLocked(intent);
18995
18996            final long origId = Binder.clearCallingIdentity();
18997            String[] requiredPermissions = requiredPermission == null ? null
18998                    : new String[] {requiredPermission};
18999            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
19000                    resultTo, resultCode, resultData, resultExtras,
19001                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
19002                    sticky, -1, uid, userId);
19003            Binder.restoreCallingIdentity(origId);
19004            return res;
19005        }
19006    }
19007
19008    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
19009        // Refuse possible leaked file descriptors
19010        if (intent != null && intent.hasFileDescriptors() == true) {
19011            throw new IllegalArgumentException("File descriptors passed in Intent");
19012        }
19013
19014        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19015                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
19016
19017        synchronized(this) {
19018            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
19019                    != PackageManager.PERMISSION_GRANTED) {
19020                String msg = "Permission Denial: unbroadcastIntent() from pid="
19021                        + Binder.getCallingPid()
19022                        + ", uid=" + Binder.getCallingUid()
19023                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19024                Slog.w(TAG, msg);
19025                throw new SecurityException(msg);
19026            }
19027            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19028            if (stickies != null) {
19029                ArrayList<Intent> list = stickies.get(intent.getAction());
19030                if (list != null) {
19031                    int N = list.size();
19032                    int i;
19033                    for (i=0; i<N; i++) {
19034                        if (intent.filterEquals(list.get(i))) {
19035                            list.remove(i);
19036                            break;
19037                        }
19038                    }
19039                    if (list.size() <= 0) {
19040                        stickies.remove(intent.getAction());
19041                    }
19042                }
19043                if (stickies.size() <= 0) {
19044                    mStickyBroadcasts.remove(userId);
19045                }
19046            }
19047        }
19048    }
19049
19050    void backgroundServicesFinishedLocked(int userId) {
19051        for (BroadcastQueue queue : mBroadcastQueues) {
19052            queue.backgroundServicesFinishedLocked(userId);
19053        }
19054    }
19055
19056    public void finishReceiver(IBinder who, int resultCode, String resultData,
19057            Bundle resultExtras, boolean resultAbort, int flags) {
19058        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
19059
19060        // Refuse possible leaked file descriptors
19061        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
19062            throw new IllegalArgumentException("File descriptors passed in Bundle");
19063        }
19064
19065        final long origId = Binder.clearCallingIdentity();
19066        try {
19067            boolean doNext = false;
19068            BroadcastRecord r;
19069
19070            synchronized(this) {
19071                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
19072                        ? mFgBroadcastQueue : mBgBroadcastQueue;
19073                r = queue.getMatchingOrderedReceiver(who);
19074                if (r != null) {
19075                    doNext = r.queue.finishReceiverLocked(r, resultCode,
19076                        resultData, resultExtras, resultAbort, true);
19077                }
19078            }
19079
19080            if (doNext) {
19081                if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
19082                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
19083                      String.format("ProcessBroadcast from %s (%s) %s", r.callerPackage,
19084                        r.callerApp == null ? "caller unknown" : r.callerApp.toShortString(),
19085                        r.intent == null ? "" : r.intent.toString()));
19086                }
19087                r.queue.processNextBroadcast(false);
19088                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
19089            }
19090            trimApplications();
19091        } finally {
19092            Binder.restoreCallingIdentity(origId);
19093        }
19094    }
19095
19096    // =========================================================
19097    // INSTRUMENTATION
19098    // =========================================================
19099
19100    public boolean startInstrumentation(ComponentName className,
19101            String profileFile, int flags, Bundle arguments,
19102            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
19103            int userId, String abiOverride) {
19104        enforceNotIsolatedCaller("startInstrumentation");
19105        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19106                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
19107        // Refuse possible leaked file descriptors
19108        if (arguments != null && arguments.hasFileDescriptors()) {
19109            throw new IllegalArgumentException("File descriptors passed in Bundle");
19110        }
19111
19112        synchronized(this) {
19113            InstrumentationInfo ii = null;
19114            ApplicationInfo ai = null;
19115            try {
19116                ii = mContext.getPackageManager().getInstrumentationInfo(
19117                    className, STOCK_PM_FLAGS);
19118                ai = AppGlobals.getPackageManager().getApplicationInfo(
19119                        ii.targetPackage, STOCK_PM_FLAGS, userId);
19120            } catch (PackageManager.NameNotFoundException e) {
19121            } catch (RemoteException e) {
19122            }
19123            if (ii == null) {
19124                reportStartInstrumentationFailureLocked(watcher, className,
19125                        "Unable to find instrumentation info for: " + className);
19126                return false;
19127            }
19128            if (ai == null) {
19129                reportStartInstrumentationFailureLocked(watcher, className,
19130                        "Unable to find instrumentation target package: " + ii.targetPackage);
19131                return false;
19132            }
19133            if (!ai.hasCode()) {
19134                reportStartInstrumentationFailureLocked(watcher, className,
19135                        "Instrumentation target has no code: " + ii.targetPackage);
19136                return false;
19137            }
19138
19139            int match = mContext.getPackageManager().checkSignatures(
19140                    ii.targetPackage, ii.packageName);
19141            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
19142                String msg = "Permission Denial: starting instrumentation "
19143                        + className + " from pid="
19144                        + Binder.getCallingPid()
19145                        + ", uid=" + Binder.getCallingPid()
19146                        + " not allowed because package " + ii.packageName
19147                        + " does not have a signature matching the target "
19148                        + ii.targetPackage;
19149                reportStartInstrumentationFailureLocked(watcher, className, msg);
19150                throw new SecurityException(msg);
19151            }
19152
19153            ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
19154            activeInstr.mClass = className;
19155            String defProcess = ai.processName;;
19156            if (ii.targetProcess == null) {
19157                activeInstr.mTargetProcesses = new String[]{ai.processName};
19158            } else if (ii.targetProcess.equals("*")) {
19159                activeInstr.mTargetProcesses = new String[0];
19160            } else {
19161                activeInstr.mTargetProcesses = ii.targetProcess.split(",");
19162                defProcess = activeInstr.mTargetProcesses[0];
19163            }
19164            activeInstr.mTargetInfo = ai;
19165            activeInstr.mProfileFile = profileFile;
19166            activeInstr.mArguments = arguments;
19167            activeInstr.mWatcher = watcher;
19168            activeInstr.mUiAutomationConnection = uiAutomationConnection;
19169            activeInstr.mResultClass = className;
19170
19171            final long origId = Binder.clearCallingIdentity();
19172            // Instrumentation can kill and relaunch even persistent processes
19173            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
19174                    "start instr");
19175            ProcessRecord app = addAppLocked(ai, defProcess, false, abiOverride);
19176            app.instr = activeInstr;
19177            activeInstr.mFinished = false;
19178            activeInstr.mRunningProcesses.add(app);
19179            if (!mActiveInstrumentation.contains(activeInstr)) {
19180                mActiveInstrumentation.add(activeInstr);
19181            }
19182            Binder.restoreCallingIdentity(origId);
19183        }
19184
19185        return true;
19186    }
19187
19188    /**
19189     * Report errors that occur while attempting to start Instrumentation.  Always writes the
19190     * error to the logs, but if somebody is watching, send the report there too.  This enables
19191     * the "am" command to report errors with more information.
19192     *
19193     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
19194     * @param cn The component name of the instrumentation.
19195     * @param report The error report.
19196     */
19197    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
19198            ComponentName cn, String report) {
19199        Slog.w(TAG, report);
19200        if (watcher != null) {
19201            Bundle results = new Bundle();
19202            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
19203            results.putString("Error", report);
19204            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
19205        }
19206    }
19207
19208    void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
19209        if (app.instr == null) {
19210            Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
19211            return;
19212        }
19213
19214        if (!app.instr.mFinished && results != null) {
19215            if (app.instr.mCurResults == null) {
19216                app.instr.mCurResults = new Bundle(results);
19217            } else {
19218                app.instr.mCurResults.putAll(results);
19219            }
19220        }
19221    }
19222
19223    public void addInstrumentationResults(IApplicationThread target, Bundle results) {
19224        int userId = UserHandle.getCallingUserId();
19225        // Refuse possible leaked file descriptors
19226        if (results != null && results.hasFileDescriptors()) {
19227            throw new IllegalArgumentException("File descriptors passed in Intent");
19228        }
19229
19230        synchronized(this) {
19231            ProcessRecord app = getRecordForAppLocked(target);
19232            if (app == null) {
19233                Slog.w(TAG, "addInstrumentationResults: no app for " + target);
19234                return;
19235            }
19236            final long origId = Binder.clearCallingIdentity();
19237            addInstrumentationResultsLocked(app, results);
19238            Binder.restoreCallingIdentity(origId);
19239        }
19240    }
19241
19242    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
19243        if (app.instr == null) {
19244            Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
19245            return;
19246        }
19247
19248        if (!app.instr.mFinished) {
19249            if (app.instr.mWatcher != null) {
19250                Bundle finalResults = app.instr.mCurResults;
19251                if (finalResults != null) {
19252                    if (app.instr.mCurResults != null && results != null) {
19253                        finalResults.putAll(results);
19254                    }
19255                } else {
19256                    finalResults = results;
19257                }
19258                mInstrumentationReporter.reportFinished(app.instr.mWatcher,
19259                        app.instr.mClass, resultCode, finalResults);
19260            }
19261
19262            // Can't call out of the system process with a lock held, so post a message.
19263            if (app.instr.mUiAutomationConnection != null) {
19264                mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
19265                        app.instr.mUiAutomationConnection).sendToTarget();
19266            }
19267            app.instr.mFinished = true;
19268        }
19269
19270        app.instr.removeProcess(app);
19271        app.instr = null;
19272
19273        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
19274                "finished inst");
19275    }
19276
19277    public void finishInstrumentation(IApplicationThread target,
19278            int resultCode, Bundle results) {
19279        int userId = UserHandle.getCallingUserId();
19280        // Refuse possible leaked file descriptors
19281        if (results != null && results.hasFileDescriptors()) {
19282            throw new IllegalArgumentException("File descriptors passed in Intent");
19283        }
19284
19285        synchronized(this) {
19286            ProcessRecord app = getRecordForAppLocked(target);
19287            if (app == null) {
19288                Slog.w(TAG, "finishInstrumentation: no app for " + target);
19289                return;
19290            }
19291            final long origId = Binder.clearCallingIdentity();
19292            finishInstrumentationLocked(app, resultCode, results);
19293            Binder.restoreCallingIdentity(origId);
19294        }
19295    }
19296
19297    // =========================================================
19298    // CONFIGURATION
19299    // =========================================================
19300
19301    public ConfigurationInfo getDeviceConfigurationInfo() {
19302        ConfigurationInfo config = new ConfigurationInfo();
19303        synchronized (this) {
19304            final Configuration globalConfig = getGlobalConfiguration();
19305            config.reqTouchScreen = globalConfig.touchscreen;
19306            config.reqKeyboardType = globalConfig.keyboard;
19307            config.reqNavigation = globalConfig.navigation;
19308            if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
19309                    || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
19310                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
19311            }
19312            if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
19313                    && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
19314                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
19315            }
19316            config.reqGlEsVersion = GL_ES_VERSION;
19317        }
19318        return config;
19319    }
19320
19321    ActivityStack getFocusedStack() {
19322        return mStackSupervisor.getFocusedStack();
19323    }
19324
19325    @Override
19326    public int getFocusedStackId() throws RemoteException {
19327        ActivityStack focusedStack = getFocusedStack();
19328        if (focusedStack != null) {
19329            return focusedStack.getStackId();
19330        }
19331        return -1;
19332    }
19333
19334    public Configuration getConfiguration() {
19335        Configuration ci;
19336        synchronized(this) {
19337            ci = new Configuration(getGlobalConfiguration());
19338            ci.userSetLocale = false;
19339        }
19340        return ci;
19341    }
19342
19343    @Override
19344    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
19345        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
19346        synchronized (this) {
19347            mSuppressResizeConfigChanges = suppress;
19348        }
19349    }
19350
19351    @Override
19352    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
19353        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
19354        if (StackId.isHomeOrRecentsStack(fromStackId)) {
19355            throw new IllegalArgumentException("You can't move tasks from the home/recents stack.");
19356        }
19357        synchronized (this) {
19358            final long origId = Binder.clearCallingIdentity();
19359            try {
19360                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
19361            } finally {
19362                Binder.restoreCallingIdentity(origId);
19363            }
19364        }
19365    }
19366
19367    @Override
19368    public void updatePersistentConfiguration(Configuration values) {
19369        enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
19370        enforceWriteSettingsPermission("updatePersistentConfiguration()");
19371        if (values == null) {
19372            throw new NullPointerException("Configuration must not be null");
19373        }
19374
19375        int userId = UserHandle.getCallingUserId();
19376
19377        synchronized(this) {
19378            updatePersistentConfigurationLocked(values, userId);
19379        }
19380    }
19381
19382    private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
19383        final long origId = Binder.clearCallingIdentity();
19384        try {
19385            updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
19386        } finally {
19387            Binder.restoreCallingIdentity(origId);
19388        }
19389    }
19390
19391    private void updateFontScaleIfNeeded(@UserIdInt int userId) {
19392        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
19393                FONT_SCALE, 1.0f, userId);
19394
19395        synchronized (this) {
19396            if (getGlobalConfiguration().fontScale == scaleFactor) {
19397                return;
19398            }
19399
19400            final Configuration configuration
19401                    = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
19402            configuration.fontScale = scaleFactor;
19403            updatePersistentConfigurationLocked(configuration, userId);
19404        }
19405    }
19406
19407    private void enforceWriteSettingsPermission(String func) {
19408        int uid = Binder.getCallingUid();
19409        if (uid == Process.ROOT_UID) {
19410            return;
19411        }
19412
19413        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
19414                Settings.getPackageNameForUid(mContext, uid), false)) {
19415            return;
19416        }
19417
19418        String msg = "Permission Denial: " + func + " from pid="
19419                + Binder.getCallingPid()
19420                + ", uid=" + uid
19421                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
19422        Slog.w(TAG, msg);
19423        throw new SecurityException(msg);
19424    }
19425
19426    @Override
19427    public boolean updateConfiguration(Configuration values) {
19428        enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
19429
19430        synchronized(this) {
19431            if (values == null && mWindowManager != null) {
19432                // sentinel: fetch the current configuration from the window manager
19433                values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
19434            }
19435
19436            if (mWindowManager != null) {
19437                // Update OOM levels based on display size.
19438                mProcessList.applyDisplaySize(mWindowManager);
19439            }
19440
19441            final long origId = Binder.clearCallingIdentity();
19442            try {
19443                if (values != null) {
19444                    Settings.System.clearConfiguration(values);
19445                }
19446                updateConfigurationLocked(values, null, false, false /* persistent */,
19447                        UserHandle.USER_NULL, false /* deferResume */,
19448                        mTmpUpdateConfigurationResult);
19449                return mTmpUpdateConfigurationResult.changes != 0;
19450            } finally {
19451                Binder.restoreCallingIdentity(origId);
19452            }
19453        }
19454    }
19455
19456    void updateUserConfigurationLocked() {
19457        final Configuration configuration = new Configuration(getGlobalConfiguration());
19458        final int currentUserId = mUserController.getCurrentUserIdLocked();
19459        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
19460                currentUserId, Settings.System.canWrite(mContext));
19461        updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
19462                false /* persistent */, currentUserId, false /* deferResume */);
19463    }
19464
19465    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19466            boolean initLocale) {
19467        return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
19468    }
19469
19470    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19471            boolean initLocale, boolean deferResume) {
19472        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
19473        return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
19474                UserHandle.USER_NULL, deferResume);
19475    }
19476
19477    // To cache the list of supported system locales
19478    private String[] mSupportedSystemLocales = null;
19479
19480    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19481            boolean initLocale, boolean persistent, int userId, boolean deferResume) {
19482        return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
19483                deferResume, null /* result */);
19484    }
19485
19486    /**
19487     * Do either or both things: (1) change the current configuration, and (2)
19488     * make sure the given activity is running with the (now) current
19489     * configuration.  Returns true if the activity has been left running, or
19490     * false if <var>starting</var> is being destroyed to match the new
19491     * configuration.
19492     *
19493     * @param userId is only used when persistent parameter is set to true to persist configuration
19494     *               for that particular user
19495     */
19496    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19497            boolean initLocale, boolean persistent, int userId, boolean deferResume,
19498            UpdateConfigurationResult result) {
19499        int changes = 0;
19500        boolean kept = true;
19501
19502        if (mWindowManager != null) {
19503            mWindowManager.deferSurfaceLayout();
19504        }
19505        try {
19506            if (values != null) {
19507                changes = updateGlobalConfiguration(values, initLocale, persistent, userId,
19508                        deferResume);
19509            }
19510
19511            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
19512        } finally {
19513            if (mWindowManager != null) {
19514                mWindowManager.continueSurfaceLayout();
19515            }
19516        }
19517
19518        if (result != null) {
19519            result.changes = changes;
19520            result.activityRelaunched = !kept;
19521        }
19522        return kept;
19523    }
19524
19525    /** Update default (global) configuration and notify listeners about changes. */
19526    private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale,
19527            boolean persistent, int userId, boolean deferResume) {
19528        mTempConfig.setTo(getGlobalConfiguration());
19529        final int changes = mTempConfig.updateFrom(values);
19530        if (changes == 0) {
19531            return 0;
19532        }
19533
19534        if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
19535                "Updating global configuration to: " + values);
19536
19537        EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
19538
19539        if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
19540            final LocaleList locales = values.getLocales();
19541            int bestLocaleIndex = 0;
19542            if (locales.size() > 1) {
19543                if (mSupportedSystemLocales == null) {
19544                    mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
19545                }
19546                bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
19547            }
19548            SystemProperties.set("persist.sys.locale",
19549                    locales.get(bestLocaleIndex).toLanguageTag());
19550            LocaleList.setDefault(locales, bestLocaleIndex);
19551            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
19552                    locales.get(bestLocaleIndex)));
19553        }
19554
19555        mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
19556        mTempConfig.seq = mConfigurationSeq;
19557
19558        // Update stored global config and notify everyone about the change.
19559        mStackSupervisor.onConfigurationChanged(mTempConfig);
19560
19561        Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
19562        // TODO(multi-display): Update UsageEvents#Event to include displayId.
19563        mUsageStatsService.reportConfigurationChange(mTempConfig,
19564                mUserController.getCurrentUserIdLocked());
19565
19566        // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
19567        mShowDialogs = shouldShowDialogs(mTempConfig, mInVrMode);
19568
19569        AttributeCache ac = AttributeCache.instance();
19570        if (ac != null) {
19571            ac.updateConfiguration(mTempConfig);
19572        }
19573
19574        // Make sure all resources in our process are updated right now, so that anyone who is going
19575        // to retrieve resource values after we return will be sure to get the new ones. This is
19576        // especially important during boot, where the first config change needs to guarantee all
19577        // resources have that config before following boot code is executed.
19578        mSystemThread.applyConfigurationToResources(mTempConfig);
19579
19580        // We need another copy of global config because we're scheduling some calls instead of
19581        // running them in place. We need to be sure that object we send will be handled unchanged.
19582        final Configuration configCopy = new Configuration(mTempConfig);
19583        if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
19584            Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
19585            msg.obj = configCopy;
19586            msg.arg1 = userId;
19587            mHandler.sendMessage(msg);
19588        }
19589
19590        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19591            ProcessRecord app = mLruProcesses.get(i);
19592            try {
19593                if (app.thread != null) {
19594                    if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
19595                            + app.processName + " new config " + configCopy);
19596                    app.thread.scheduleConfigurationChanged(configCopy);
19597                }
19598            } catch (Exception e) {
19599            }
19600        }
19601
19602        Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
19603        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
19604                | Intent.FLAG_RECEIVER_FOREGROUND);
19605        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
19606                AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID,
19607                UserHandle.USER_ALL);
19608        if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
19609            intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
19610            intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
19611                    | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
19612            if (initLocale || !mProcessesReady) {
19613                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19614            }
19615            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
19616                    AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID,
19617                    UserHandle.USER_ALL);
19618        }
19619
19620        // Override configuration of the default display duplicates global config, so we need to
19621        // update it also. This will also notify WindowManager about changes.
19622        performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
19623                DEFAULT_DISPLAY);
19624
19625        return changes;
19626    }
19627
19628    @Override
19629    public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
19630        enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
19631
19632        synchronized (this) {
19633            // Check if display is initialized in AM.
19634            if (!mStackSupervisor.isDisplayAdded(displayId)) {
19635                // Call might come when display is not yet added or has already been removed.
19636                if (DEBUG_CONFIGURATION) {
19637                    Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
19638                            + displayId);
19639                }
19640                return false;
19641            }
19642
19643            if (values == null && mWindowManager != null) {
19644                // sentinel: fetch the current configuration from the window manager
19645                values = mWindowManager.computeNewConfiguration(displayId);
19646            }
19647
19648            if (mWindowManager != null) {
19649                // Update OOM levels based on display size.
19650                mProcessList.applyDisplaySize(mWindowManager);
19651            }
19652
19653            final long origId = Binder.clearCallingIdentity();
19654            try {
19655                if (values != null) {
19656                    Settings.System.clearConfiguration(values);
19657                }
19658                updateDisplayOverrideConfigurationLocked(values, null /* starting */,
19659                        false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
19660                return mTmpUpdateConfigurationResult.changes != 0;
19661            } finally {
19662                Binder.restoreCallingIdentity(origId);
19663            }
19664        }
19665    }
19666
19667    boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
19668            boolean deferResume, int displayId) {
19669        return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
19670                displayId, null /* result */);
19671    }
19672
19673    /**
19674     * Updates override configuration specific for the selected display. If no config is provided,
19675     * new one will be computed in WM based on current display info.
19676     */
19677    private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
19678            ActivityRecord starting, boolean deferResume, int displayId,
19679            UpdateConfigurationResult result) {
19680        int changes = 0;
19681        boolean kept = true;
19682
19683        if (mWindowManager != null) {
19684            mWindowManager.deferSurfaceLayout();
19685        }
19686        try {
19687            if (values != null) {
19688                if (displayId == DEFAULT_DISPLAY) {
19689                    // Override configuration of the default display duplicates global config, so
19690                    // we're calling global config update instead for default display. It will also
19691                    // apply the correct override config.
19692                    changes = updateGlobalConfiguration(values, false /* initLocale */,
19693                            false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
19694                } else {
19695                    changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
19696                }
19697            }
19698
19699            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
19700        } finally {
19701            if (mWindowManager != null) {
19702                mWindowManager.continueSurfaceLayout();
19703            }
19704        }
19705
19706        if (result != null) {
19707            result.changes = changes;
19708            result.activityRelaunched = !kept;
19709        }
19710        return kept;
19711    }
19712
19713    private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
19714            int displayId) {
19715        mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
19716        final int changes = mTempConfig.updateFrom(values);
19717        if (changes == 0) {
19718            return 0;
19719        }
19720
19721        Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " " + mTempConfig
19722                + " for displayId=" + displayId);
19723        mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
19724
19725        final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
19726        if (isDensityChange) {
19727            // Reset the unsupported display size dialog.
19728            mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
19729
19730            killAllBackgroundProcessesExcept(N, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
19731        }
19732
19733        // Update the configuration with WM first and check if any of the stacks need to be resized
19734        // due to the configuration change. If so, resize the stacks now and do any relaunches if
19735        // necessary. This way we don't need to relaunch again afterwards in
19736        // ensureActivityConfigurationLocked().
19737        if (mWindowManager != null) {
19738            final int[] resizedStacks =
19739                    mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
19740            if (resizedStacks != null) {
19741                for (int stackId : resizedStacks) {
19742                    resizeStackWithBoundsFromWindowManager(stackId, deferResume);
19743                }
19744            }
19745        }
19746
19747        return changes;
19748    }
19749
19750    /** Applies latest configuration and/or visibility updates if needed. */
19751    private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
19752        boolean kept = true;
19753        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
19754        // mainStack is null during startup.
19755        if (mainStack != null) {
19756            if (changes != 0 && starting == null) {
19757                // If the configuration changed, and the caller is not already
19758                // in the process of starting an activity, then find the top
19759                // activity to check if its configuration needs to change.
19760                starting = mainStack.topRunningActivityLocked();
19761            }
19762
19763            if (starting != null) {
19764                kept = starting.ensureActivityConfigurationLocked(changes,
19765                        false /* preserveWindow */);
19766                // And we need to make sure at this point that all other activities
19767                // are made visible with the correct configuration.
19768                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
19769                        !PRESERVE_WINDOWS);
19770            }
19771        }
19772
19773        return kept;
19774    }
19775
19776    /** Helper method that requests bounds from WM and applies them to stack. */
19777    private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
19778        final Rect newStackBounds = new Rect();
19779        final Rect newTempTaskBounds = new Rect();
19780        mStackSupervisor.getStack(stackId).getBoundsForNewConfiguration(newStackBounds,
19781                newTempTaskBounds);
19782        mStackSupervisor.resizeStackLocked(
19783                stackId, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
19784                !newTempTaskBounds.isEmpty() ? newTempTaskBounds : null /* tempTaskBounds */,
19785                null /* tempTaskInsetBounds */, false /* preserveWindows */,
19786                false /* allowResizeInDockedMode */, deferResume);
19787    }
19788
19789    /**
19790     * Decide based on the configuration whether we should show the ANR,
19791     * crash, etc dialogs.  The idea is that if there is no affordance to
19792     * press the on-screen buttons, or the user experience would be more
19793     * greatly impacted than the crash itself, we shouldn't show the dialog.
19794     *
19795     * A thought: SystemUI might also want to get told about this, the Power
19796     * dialog / global actions also might want different behaviors.
19797     */
19798    private static boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
19799        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
19800                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
19801                                   && config.navigation == Configuration.NAVIGATION_NONAV);
19802        int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
19803        final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
19804                && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE))
19805                && modeType != Configuration.UI_MODE_TYPE_TELEVISION);
19806        return inputMethodExists && uiModeSupportsDialogs && !inVrMode;
19807    }
19808
19809    @Override
19810    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
19811        synchronized (this) {
19812            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
19813            if (srec != null) {
19814                return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
19815            }
19816        }
19817        return false;
19818    }
19819
19820    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
19821            Intent resultData) {
19822
19823        synchronized (this) {
19824            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
19825            if (r != null) {
19826                return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
19827            }
19828            return false;
19829        }
19830    }
19831
19832    public int getLaunchedFromUid(IBinder activityToken) {
19833        ActivityRecord srec;
19834        synchronized (this) {
19835            srec = ActivityRecord.forTokenLocked(activityToken);
19836        }
19837        if (srec == null) {
19838            return -1;
19839        }
19840        return srec.launchedFromUid;
19841    }
19842
19843    public String getLaunchedFromPackage(IBinder activityToken) {
19844        ActivityRecord srec;
19845        synchronized (this) {
19846            srec = ActivityRecord.forTokenLocked(activityToken);
19847        }
19848        if (srec == null) {
19849            return null;
19850        }
19851        return srec.launchedFromPackage;
19852    }
19853
19854    // =========================================================
19855    // LIFETIME MANAGEMENT
19856    // =========================================================
19857
19858    // Returns whether the app is receiving broadcast.
19859    // If receiving, fetch all broadcast queues which the app is
19860    // the current [or imminent] receiver on.
19861    private boolean isReceivingBroadcastLocked(ProcessRecord app,
19862            ArraySet<BroadcastQueue> receivingQueues) {
19863        if (!app.curReceivers.isEmpty()) {
19864            for (BroadcastRecord r : app.curReceivers) {
19865                receivingQueues.add(r.queue);
19866            }
19867            return true;
19868        }
19869
19870        // It's not the current receiver, but it might be starting up to become one
19871        for (BroadcastQueue queue : mBroadcastQueues) {
19872            final BroadcastRecord r = queue.mPendingBroadcast;
19873            if (r != null && r.curApp == app) {
19874                // found it; report which queue it's in
19875                receivingQueues.add(queue);
19876            }
19877        }
19878
19879        return !receivingQueues.isEmpty();
19880    }
19881
19882    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
19883            int targetUid, ComponentName targetComponent, String targetProcess) {
19884        if (!mTrackingAssociations) {
19885            return null;
19886        }
19887        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19888                = mAssociations.get(targetUid);
19889        if (components == null) {
19890            components = new ArrayMap<>();
19891            mAssociations.put(targetUid, components);
19892        }
19893        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19894        if (sourceUids == null) {
19895            sourceUids = new SparseArray<>();
19896            components.put(targetComponent, sourceUids);
19897        }
19898        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19899        if (sourceProcesses == null) {
19900            sourceProcesses = new ArrayMap<>();
19901            sourceUids.put(sourceUid, sourceProcesses);
19902        }
19903        Association ass = sourceProcesses.get(sourceProcess);
19904        if (ass == null) {
19905            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
19906                    targetProcess);
19907            sourceProcesses.put(sourceProcess, ass);
19908        }
19909        ass.mCount++;
19910        ass.mNesting++;
19911        if (ass.mNesting == 1) {
19912            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
19913            ass.mLastState = sourceState;
19914        }
19915        return ass;
19916    }
19917
19918    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
19919            ComponentName targetComponent) {
19920        if (!mTrackingAssociations) {
19921            return;
19922        }
19923        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19924                = mAssociations.get(targetUid);
19925        if (components == null) {
19926            return;
19927        }
19928        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19929        if (sourceUids == null) {
19930            return;
19931        }
19932        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19933        if (sourceProcesses == null) {
19934            return;
19935        }
19936        Association ass = sourceProcesses.get(sourceProcess);
19937        if (ass == null || ass.mNesting <= 0) {
19938            return;
19939        }
19940        ass.mNesting--;
19941        if (ass.mNesting == 0) {
19942            long uptime = SystemClock.uptimeMillis();
19943            ass.mTime += uptime - ass.mStartTime;
19944            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19945                    += uptime - ass.mLastStateUptime;
19946            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
19947        }
19948    }
19949
19950    private void noteUidProcessState(final int uid, final int state) {
19951        mBatteryStatsService.noteUidProcessState(uid, state);
19952        if (mTrackingAssociations) {
19953            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
19954                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
19955                        = mAssociations.valueAt(i1);
19956                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
19957                    SparseArray<ArrayMap<String, Association>> sourceUids
19958                            = targetComponents.valueAt(i2);
19959                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
19960                    if (sourceProcesses != null) {
19961                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
19962                            Association ass = sourceProcesses.valueAt(i4);
19963                            if (ass.mNesting >= 1) {
19964                                // currently associated
19965                                long uptime = SystemClock.uptimeMillis();
19966                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19967                                        += uptime - ass.mLastStateUptime;
19968                                ass.mLastState = state;
19969                                ass.mLastStateUptime = uptime;
19970                            }
19971                        }
19972                    }
19973                }
19974            }
19975        }
19976    }
19977
19978    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
19979            boolean doingAll, long now) {
19980        if (mAdjSeq == app.adjSeq) {
19981            // This adjustment has already been computed.
19982            return app.curRawAdj;
19983        }
19984
19985        if (app.thread == null) {
19986            app.adjSeq = mAdjSeq;
19987            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19988            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19989            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
19990        }
19991
19992        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
19993        app.adjSource = null;
19994        app.adjTarget = null;
19995        app.empty = false;
19996        app.cached = false;
19997
19998        final int activitiesSize = app.activities.size();
19999
20000        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
20001            // The max adjustment doesn't allow this app to be anything
20002            // below foreground, so it is not worth doing work for it.
20003            app.adjType = "fixed";
20004            app.adjSeq = mAdjSeq;
20005            app.curRawAdj = app.maxAdj;
20006            app.foregroundActivities = false;
20007            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20008            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
20009            // System processes can do UI, and when they do we want to have
20010            // them trim their memory after the user leaves the UI.  To
20011            // facilitate this, here we need to determine whether or not it
20012            // is currently showing UI.
20013            app.systemNoUi = true;
20014            if (app == TOP_APP) {
20015                app.systemNoUi = false;
20016                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20017                app.adjType = "pers-top-activity";
20018            } else if (app.hasTopUi) {
20019                app.systemNoUi = false;
20020                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20021                app.adjType = "pers-top-ui";
20022            } else if (activitiesSize > 0) {
20023                for (int j = 0; j < activitiesSize; j++) {
20024                    final ActivityRecord r = app.activities.get(j);
20025                    if (r.visible) {
20026                        app.systemNoUi = false;
20027                    }
20028                }
20029            }
20030            if (!app.systemNoUi) {
20031                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
20032            }
20033            return (app.curAdj=app.maxAdj);
20034        }
20035
20036        app.systemNoUi = false;
20037
20038        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
20039
20040        // Determine the importance of the process, starting with most
20041        // important to least, and assign an appropriate OOM adjustment.
20042        int adj;
20043        int schedGroup;
20044        int procState;
20045        boolean foregroundActivities = false;
20046        mTmpBroadcastQueue.clear();
20047        if (app == TOP_APP) {
20048            // The last app on the list is the foreground app.
20049            adj = ProcessList.FOREGROUND_APP_ADJ;
20050            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20051            app.adjType = "top-activity";
20052            foregroundActivities = true;
20053            procState = PROCESS_STATE_CUR_TOP;
20054        } else if (app.instr != null) {
20055            // Don't want to kill running instrumentation.
20056            adj = ProcessList.FOREGROUND_APP_ADJ;
20057            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20058            app.adjType = "instrumentation";
20059            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
20060        } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
20061            // An app that is currently receiving a broadcast also
20062            // counts as being in the foreground for OOM killer purposes.
20063            // It's placed in a sched group based on the nature of the
20064            // broadcast as reflected by which queue it's active in.
20065            adj = ProcessList.FOREGROUND_APP_ADJ;
20066            schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
20067                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20068            app.adjType = "broadcast";
20069            procState = ActivityManager.PROCESS_STATE_RECEIVER;
20070        } else if (app.executingServices.size() > 0) {
20071            // An app that is currently executing a service callback also
20072            // counts as being in the foreground.
20073            adj = ProcessList.FOREGROUND_APP_ADJ;
20074            schedGroup = app.execServicesFg ?
20075                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20076            app.adjType = "exec-service";
20077            procState = ActivityManager.PROCESS_STATE_SERVICE;
20078            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
20079        } else {
20080            // As far as we know the process is empty.  We may change our mind later.
20081            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20082            // At this point we don't actually know the adjustment.  Use the cached adj
20083            // value that the caller wants us to.
20084            adj = cachedAdj;
20085            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20086            app.cached = true;
20087            app.empty = true;
20088            app.adjType = "cch-empty";
20089        }
20090
20091        // Examine all activities if not already foreground.
20092        if (!foregroundActivities && activitiesSize > 0) {
20093            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
20094            for (int j = 0; j < activitiesSize; j++) {
20095                final ActivityRecord r = app.activities.get(j);
20096                if (r.app != app) {
20097                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
20098                            + " instead of expected " + app);
20099                    if (r.app == null || (r.app.uid == app.uid)) {
20100                        // Only fix things up when they look sane
20101                        r.app = app;
20102                    } else {
20103                        continue;
20104                    }
20105                }
20106                if (r.visible) {
20107                    // App has a visible activity; only upgrade adjustment.
20108                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
20109                        adj = ProcessList.VISIBLE_APP_ADJ;
20110                        app.adjType = "visible";
20111                    }
20112                    if (procState > PROCESS_STATE_CUR_TOP) {
20113                        procState = PROCESS_STATE_CUR_TOP;
20114                    }
20115                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20116                    app.cached = false;
20117                    app.empty = false;
20118                    foregroundActivities = true;
20119                    if (r.task != null && minLayer > 0) {
20120                        final int layer = r.task.mLayerRank;
20121                        if (layer >= 0 && minLayer > layer) {
20122                            minLayer = layer;
20123                        }
20124                    }
20125                    break;
20126                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
20127                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20128                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20129                        app.adjType = "pausing";
20130                    }
20131                    if (procState > PROCESS_STATE_CUR_TOP) {
20132                        procState = PROCESS_STATE_CUR_TOP;
20133                    }
20134                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20135                    app.cached = false;
20136                    app.empty = false;
20137                    foregroundActivities = true;
20138                } else if (r.state == ActivityState.STOPPING) {
20139                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20140                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20141                        app.adjType = "stopping";
20142                    }
20143                    // For the process state, we will at this point consider the
20144                    // process to be cached.  It will be cached either as an activity
20145                    // or empty depending on whether the activity is finishing.  We do
20146                    // this so that we can treat the process as cached for purposes of
20147                    // memory trimming (determing current memory level, trim command to
20148                    // send to process) since there can be an arbitrary number of stopping
20149                    // processes and they should soon all go into the cached state.
20150                    if (!r.finishing) {
20151                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
20152                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
20153                        }
20154                    }
20155                    app.cached = false;
20156                    app.empty = false;
20157                    foregroundActivities = true;
20158                } else {
20159                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
20160                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
20161                        app.adjType = "cch-act";
20162                    }
20163                }
20164            }
20165            if (adj == ProcessList.VISIBLE_APP_ADJ) {
20166                adj += minLayer;
20167            }
20168        }
20169
20170        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
20171                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
20172            if (app.foregroundServices) {
20173                // The user is aware of this app, so make it visible.
20174                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20175                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
20176                app.cached = false;
20177                app.adjType = "fg-service";
20178                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20179            } else if (app.forcingToForeground != null) {
20180                // The user is aware of this app, so make it visible.
20181                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20182                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20183                app.cached = false;
20184                app.adjType = "force-fg";
20185                app.adjSource = app.forcingToForeground;
20186                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20187            } else if (app.hasOverlayUi) {
20188                // The process is display an overlay UI.
20189                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20190                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20191                app.cached = false;
20192                app.adjType = "has-overlay-ui";
20193                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20194            }
20195        }
20196
20197        if (app == mHeavyWeightProcess) {
20198            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
20199                // We don't want to kill the current heavy-weight process.
20200                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
20201                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20202                app.cached = false;
20203                app.adjType = "heavy";
20204            }
20205            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20206                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
20207            }
20208        }
20209
20210        if (app == mHomeProcess) {
20211            if (adj > ProcessList.HOME_APP_ADJ) {
20212                // This process is hosting what we currently consider to be the
20213                // home app, so we don't want to let it go into the background.
20214                adj = ProcessList.HOME_APP_ADJ;
20215                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20216                app.cached = false;
20217                app.adjType = "home";
20218            }
20219            if (procState > ActivityManager.PROCESS_STATE_HOME) {
20220                procState = ActivityManager.PROCESS_STATE_HOME;
20221            }
20222        }
20223
20224        if (app == mPreviousProcess && app.activities.size() > 0) {
20225            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
20226                // This was the previous process that showed UI to the user.
20227                // We want to try to keep it around more aggressively, to give
20228                // a good experience around switching between two apps.
20229                adj = ProcessList.PREVIOUS_APP_ADJ;
20230                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20231                app.cached = false;
20232                app.adjType = "previous";
20233            }
20234            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
20235                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
20236            }
20237        }
20238
20239        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
20240                + " reason=" + app.adjType);
20241
20242        // By default, we use the computed adjustment.  It may be changed if
20243        // there are applications dependent on our services or providers, but
20244        // this gives us a baseline and makes sure we don't get into an
20245        // infinite recursion.
20246        app.adjSeq = mAdjSeq;
20247        app.curRawAdj = adj;
20248        app.hasStartedServices = false;
20249
20250        if (mBackupTarget != null && app == mBackupTarget.app) {
20251            // If possible we want to avoid killing apps while they're being backed up
20252            if (adj > ProcessList.BACKUP_APP_ADJ) {
20253                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
20254                adj = ProcessList.BACKUP_APP_ADJ;
20255                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
20256                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
20257                }
20258                app.adjType = "backup";
20259                app.cached = false;
20260            }
20261            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
20262                procState = ActivityManager.PROCESS_STATE_BACKUP;
20263            }
20264        }
20265
20266        boolean mayBeTop = false;
20267
20268        for (int is = app.services.size()-1;
20269                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
20270                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
20271                        || procState > ActivityManager.PROCESS_STATE_TOP);
20272                is--) {
20273            ServiceRecord s = app.services.valueAt(is);
20274            if (s.startRequested) {
20275                app.hasStartedServices = true;
20276                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
20277                    procState = ActivityManager.PROCESS_STATE_SERVICE;
20278                }
20279                if (app.hasShownUi && app != mHomeProcess) {
20280                    // If this process has shown some UI, let it immediately
20281                    // go to the LRU list because it may be pretty heavy with
20282                    // UI stuff.  We'll tag it with a label just to help
20283                    // debug and understand what is going on.
20284                    if (adj > ProcessList.SERVICE_ADJ) {
20285                        app.adjType = "cch-started-ui-services";
20286                    }
20287                } else {
20288                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
20289                        // This service has seen some activity within
20290                        // recent memory, so we will keep its process ahead
20291                        // of the background processes.
20292                        if (adj > ProcessList.SERVICE_ADJ) {
20293                            adj = ProcessList.SERVICE_ADJ;
20294                            app.adjType = "started-services";
20295                            app.cached = false;
20296                        }
20297                    }
20298                    // If we have let the service slide into the background
20299                    // state, still have some text describing what it is doing
20300                    // even though the service no longer has an impact.
20301                    if (adj > ProcessList.SERVICE_ADJ) {
20302                        app.adjType = "cch-started-services";
20303                    }
20304                }
20305            }
20306
20307            for (int conni = s.connections.size()-1;
20308                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
20309                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
20310                            || procState > ActivityManager.PROCESS_STATE_TOP);
20311                    conni--) {
20312                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
20313                for (int i = 0;
20314                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
20315                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
20316                                || procState > ActivityManager.PROCESS_STATE_TOP);
20317                        i++) {
20318                    // XXX should compute this based on the max of
20319                    // all connected clients.
20320                    ConnectionRecord cr = clist.get(i);
20321                    if (cr.binding.client == app) {
20322                        // Binding to ourself is not interesting.
20323                        continue;
20324                    }
20325
20326                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
20327                        ProcessRecord client = cr.binding.client;
20328                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
20329                                TOP_APP, doingAll, now);
20330                        int clientProcState = client.curProcState;
20331                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
20332                            // If the other app is cached for any reason, for purposes here
20333                            // we are going to consider it empty.  The specific cached state
20334                            // doesn't propagate except under certain conditions.
20335                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20336                        }
20337                        String adjType = null;
20338                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
20339                            // Not doing bind OOM management, so treat
20340                            // this guy more like a started service.
20341                            if (app.hasShownUi && app != mHomeProcess) {
20342                                // If this process has shown some UI, let it immediately
20343                                // go to the LRU list because it may be pretty heavy with
20344                                // UI stuff.  We'll tag it with a label just to help
20345                                // debug and understand what is going on.
20346                                if (adj > clientAdj) {
20347                                    adjType = "cch-bound-ui-services";
20348                                }
20349                                app.cached = false;
20350                                clientAdj = adj;
20351                                clientProcState = procState;
20352                            } else {
20353                                if (now >= (s.lastActivity
20354                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
20355                                    // This service has not seen activity within
20356                                    // recent memory, so allow it to drop to the
20357                                    // LRU list if there is no other reason to keep
20358                                    // it around.  We'll also tag it with a label just
20359                                    // to help debug and undertand what is going on.
20360                                    if (adj > clientAdj) {
20361                                        adjType = "cch-bound-services";
20362                                    }
20363                                    clientAdj = adj;
20364                                }
20365                            }
20366                        }
20367                        if (adj > clientAdj) {
20368                            // If this process has recently shown UI, and
20369                            // the process that is binding to it is less
20370                            // important than being visible, then we don't
20371                            // care about the binding as much as we care
20372                            // about letting this process get into the LRU
20373                            // list to be killed and restarted if needed for
20374                            // memory.
20375                            if (app.hasShownUi && app != mHomeProcess
20376                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20377                                adjType = "cch-bound-ui-services";
20378                            } else {
20379                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
20380                                        |Context.BIND_IMPORTANT)) != 0) {
20381                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
20382                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
20383                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
20384                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
20385                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20386                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20387                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
20388                                    adj = clientAdj;
20389                                } else {
20390                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
20391                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
20392                                    }
20393                                }
20394                                if (!client.cached) {
20395                                    app.cached = false;
20396                                }
20397                                adjType = "service";
20398                            }
20399                        }
20400                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
20401                            // This will treat important bound services identically to
20402                            // the top app, which may behave differently than generic
20403                            // foreground work.
20404                            if (client.curSchedGroup > schedGroup) {
20405                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
20406                                    schedGroup = client.curSchedGroup;
20407                                } else {
20408                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20409                                }
20410                            }
20411                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
20412                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
20413                                    // Special handling of clients who are in the top state.
20414                                    // We *may* want to consider this process to be in the
20415                                    // top state as well, but only if there is not another
20416                                    // reason for it to be running.  Being on the top is a
20417                                    // special state, meaning you are specifically running
20418                                    // for the current top app.  If the process is already
20419                                    // running in the background for some other reason, it
20420                                    // is more important to continue considering it to be
20421                                    // in the background state.
20422                                    mayBeTop = true;
20423                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20424                                } else {
20425                                    // Special handling for above-top states (persistent
20426                                    // processes).  These should not bring the current process
20427                                    // into the top state, since they are not on top.  Instead
20428                                    // give them the best state after that.
20429                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
20430                                        clientProcState =
20431                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
20432                                    } else if (mWakefulness
20433                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
20434                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
20435                                                    != 0) {
20436                                        clientProcState =
20437                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
20438                                    } else {
20439                                        clientProcState =
20440                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20441                                    }
20442                                }
20443                            }
20444                        } else {
20445                            if (clientProcState <
20446                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
20447                                clientProcState =
20448                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
20449                            }
20450                        }
20451                        if (procState > clientProcState) {
20452                            procState = clientProcState;
20453                        }
20454                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20455                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
20456                            app.pendingUiClean = true;
20457                        }
20458                        if (adjType != null) {
20459                            app.adjType = adjType;
20460                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
20461                                    .REASON_SERVICE_IN_USE;
20462                            app.adjSource = cr.binding.client;
20463                            app.adjSourceProcState = clientProcState;
20464                            app.adjTarget = s.name;
20465                        }
20466                    }
20467                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
20468                        app.treatLikeActivity = true;
20469                    }
20470                    final ActivityRecord a = cr.activity;
20471                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
20472                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
20473                            (a.visible || a.state == ActivityState.RESUMED ||
20474                             a.state == ActivityState.PAUSING)) {
20475                            adj = ProcessList.FOREGROUND_APP_ADJ;
20476                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
20477                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
20478                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
20479                                } else {
20480                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20481                                }
20482                            }
20483                            app.cached = false;
20484                            app.adjType = "service";
20485                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
20486                                    .REASON_SERVICE_IN_USE;
20487                            app.adjSource = a;
20488                            app.adjSourceProcState = procState;
20489                            app.adjTarget = s.name;
20490                        }
20491                    }
20492                }
20493            }
20494        }
20495
20496        for (int provi = app.pubProviders.size()-1;
20497                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
20498                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
20499                        || procState > ActivityManager.PROCESS_STATE_TOP);
20500                provi--) {
20501            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
20502            for (int i = cpr.connections.size()-1;
20503                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
20504                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
20505                            || procState > ActivityManager.PROCESS_STATE_TOP);
20506                    i--) {
20507                ContentProviderConnection conn = cpr.connections.get(i);
20508                ProcessRecord client = conn.client;
20509                if (client == app) {
20510                    // Being our own client is not interesting.
20511                    continue;
20512                }
20513                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
20514                int clientProcState = client.curProcState;
20515                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
20516                    // If the other app is cached for any reason, for purposes here
20517                    // we are going to consider it empty.
20518                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20519                }
20520                if (adj > clientAdj) {
20521                    if (app.hasShownUi && app != mHomeProcess
20522                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20523                        app.adjType = "cch-ui-provider";
20524                    } else {
20525                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
20526                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
20527                        app.adjType = "provider";
20528                    }
20529                    app.cached &= client.cached;
20530                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
20531                            .REASON_PROVIDER_IN_USE;
20532                    app.adjSource = client;
20533                    app.adjSourceProcState = clientProcState;
20534                    app.adjTarget = cpr.name;
20535                }
20536                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
20537                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
20538                        // Special handling of clients who are in the top state.
20539                        // We *may* want to consider this process to be in the
20540                        // top state as well, but only if there is not another
20541                        // reason for it to be running.  Being on the top is a
20542                        // special state, meaning you are specifically running
20543                        // for the current top app.  If the process is already
20544                        // running in the background for some other reason, it
20545                        // is more important to continue considering it to be
20546                        // in the background state.
20547                        mayBeTop = true;
20548                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20549                    } else {
20550                        // Special handling for above-top states (persistent
20551                        // processes).  These should not bring the current process
20552                        // into the top state, since they are not on top.  Instead
20553                        // give them the best state after that.
20554                        clientProcState =
20555                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
20556                    }
20557                }
20558                if (procState > clientProcState) {
20559                    procState = clientProcState;
20560                }
20561                if (client.curSchedGroup > schedGroup) {
20562                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20563                }
20564            }
20565            // If the provider has external (non-framework) process
20566            // dependencies, ensure that its adjustment is at least
20567            // FOREGROUND_APP_ADJ.
20568            if (cpr.hasExternalProcessHandles()) {
20569                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
20570                    adj = ProcessList.FOREGROUND_APP_ADJ;
20571                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20572                    app.cached = false;
20573                    app.adjType = "provider";
20574                    app.adjTarget = cpr.name;
20575                }
20576                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20577                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20578                }
20579            }
20580        }
20581
20582        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
20583            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
20584                adj = ProcessList.PREVIOUS_APP_ADJ;
20585                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20586                app.cached = false;
20587                app.adjType = "provider";
20588            }
20589            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
20590                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
20591            }
20592        }
20593
20594        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
20595            // A client of one of our services or providers is in the top state.  We
20596            // *may* want to be in the top state, but not if we are already running in
20597            // the background for some other reason.  For the decision here, we are going
20598            // to pick out a few specific states that we want to remain in when a client
20599            // is top (states that tend to be longer-term) and otherwise allow it to go
20600            // to the top state.
20601            switch (procState) {
20602                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
20603                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
20604                case ActivityManager.PROCESS_STATE_SERVICE:
20605                    // These all are longer-term states, so pull them up to the top
20606                    // of the background states, but not all the way to the top state.
20607                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
20608                    break;
20609                default:
20610                    // Otherwise, top is a better choice, so take it.
20611                    procState = ActivityManager.PROCESS_STATE_TOP;
20612                    break;
20613            }
20614        }
20615
20616        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
20617            if (app.hasClientActivities) {
20618                // This is a cached process, but with client activities.  Mark it so.
20619                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
20620                app.adjType = "cch-client-act";
20621            } else if (app.treatLikeActivity) {
20622                // This is a cached process, but somebody wants us to treat it like it has
20623                // an activity, okay!
20624                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
20625                app.adjType = "cch-as-act";
20626            }
20627        }
20628
20629        if (adj == ProcessList.SERVICE_ADJ) {
20630            if (doingAll) {
20631                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
20632                mNewNumServiceProcs++;
20633                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
20634                if (!app.serviceb) {
20635                    // This service isn't far enough down on the LRU list to
20636                    // normally be a B service, but if we are low on RAM and it
20637                    // is large we want to force it down since we would prefer to
20638                    // keep launcher over it.
20639                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
20640                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
20641                        app.serviceHighRam = true;
20642                        app.serviceb = true;
20643                        //Slog.i(TAG, "ADJ " + app + " high ram!");
20644                    } else {
20645                        mNewNumAServiceProcs++;
20646                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
20647                    }
20648                } else {
20649                    app.serviceHighRam = false;
20650                }
20651            }
20652            if (app.serviceb) {
20653                adj = ProcessList.SERVICE_B_ADJ;
20654            }
20655        }
20656
20657        app.curRawAdj = adj;
20658
20659        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
20660        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
20661        if (adj > app.maxAdj) {
20662            adj = app.maxAdj;
20663            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
20664                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20665            }
20666        }
20667
20668        // Do final modification to adj.  Everything we do between here and applying
20669        // the final setAdj must be done in this function, because we will also use
20670        // it when computing the final cached adj later.  Note that we don't need to
20671        // worry about this for max adj above, since max adj will always be used to
20672        // keep it out of the cached vaues.
20673        app.curAdj = app.modifyRawOomAdj(adj);
20674        app.curSchedGroup = schedGroup;
20675        app.curProcState = procState;
20676        app.foregroundActivities = foregroundActivities;
20677
20678        return app.curRawAdj;
20679    }
20680
20681    /**
20682     * Record new PSS sample for a process.
20683     */
20684    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
20685            long now) {
20686        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
20687                swapPss * 1024);
20688        proc.lastPssTime = now;
20689        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
20690        if (DEBUG_PSS) Slog.d(TAG_PSS,
20691                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
20692                + " state=" + ProcessList.makeProcStateString(procState));
20693        if (proc.initialIdlePss == 0) {
20694            proc.initialIdlePss = pss;
20695        }
20696        proc.lastPss = pss;
20697        proc.lastSwapPss = swapPss;
20698        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
20699            proc.lastCachedPss = pss;
20700            proc.lastCachedSwapPss = swapPss;
20701        }
20702
20703        final SparseArray<Pair<Long, String>> watchUids
20704                = mMemWatchProcesses.getMap().get(proc.processName);
20705        Long check = null;
20706        if (watchUids != null) {
20707            Pair<Long, String> val = watchUids.get(proc.uid);
20708            if (val == null) {
20709                val = watchUids.get(0);
20710            }
20711            if (val != null) {
20712                check = val.first;
20713            }
20714        }
20715        if (check != null) {
20716            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
20717                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20718                if (!isDebuggable) {
20719                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
20720                        isDebuggable = true;
20721                    }
20722                }
20723                if (isDebuggable) {
20724                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
20725                    final ProcessRecord myProc = proc;
20726                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
20727                    mMemWatchDumpProcName = proc.processName;
20728                    mMemWatchDumpFile = heapdumpFile.toString();
20729                    mMemWatchDumpPid = proc.pid;
20730                    mMemWatchDumpUid = proc.uid;
20731                    BackgroundThread.getHandler().post(new Runnable() {
20732                        @Override
20733                        public void run() {
20734                            revokeUriPermission(ActivityThread.currentActivityThread()
20735                                            .getApplicationThread(),
20736                                    DumpHeapActivity.JAVA_URI,
20737                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
20738                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
20739                                    UserHandle.myUserId());
20740                            ParcelFileDescriptor fd = null;
20741                            try {
20742                                heapdumpFile.delete();
20743                                fd = ParcelFileDescriptor.open(heapdumpFile,
20744                                        ParcelFileDescriptor.MODE_CREATE |
20745                                                ParcelFileDescriptor.MODE_TRUNCATE |
20746                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
20747                                                ParcelFileDescriptor.MODE_APPEND);
20748                                IApplicationThread thread = myProc.thread;
20749                                if (thread != null) {
20750                                    try {
20751                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
20752                                                "Requesting dump heap from "
20753                                                + myProc + " to " + heapdumpFile);
20754                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
20755                                    } catch (RemoteException e) {
20756                                    }
20757                                }
20758                            } catch (FileNotFoundException e) {
20759                                e.printStackTrace();
20760                            } finally {
20761                                if (fd != null) {
20762                                    try {
20763                                        fd.close();
20764                                    } catch (IOException e) {
20765                                    }
20766                                }
20767                            }
20768                        }
20769                    });
20770                } else {
20771                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
20772                            + ", but debugging not enabled");
20773                }
20774            }
20775        }
20776    }
20777
20778    /**
20779     * Schedule PSS collection of a process.
20780     */
20781    void requestPssLocked(ProcessRecord proc, int procState) {
20782        if (mPendingPssProcesses.contains(proc)) {
20783            return;
20784        }
20785        if (mPendingPssProcesses.size() == 0) {
20786            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20787        }
20788        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
20789        proc.pssProcState = procState;
20790        mPendingPssProcesses.add(proc);
20791    }
20792
20793    /**
20794     * Schedule PSS collection of all processes.
20795     */
20796    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
20797        if (!always) {
20798            if (now < (mLastFullPssTime +
20799                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
20800                return;
20801            }
20802        }
20803        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
20804        mLastFullPssTime = now;
20805        mFullPssPending = true;
20806        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
20807        mPendingPssProcesses.clear();
20808        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20809            ProcessRecord app = mLruProcesses.get(i);
20810            if (app.thread == null
20811                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
20812                continue;
20813            }
20814            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
20815                app.pssProcState = app.setProcState;
20816                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20817                        mTestPssMode, isSleepingLocked(), now);
20818                mPendingPssProcesses.add(app);
20819            }
20820        }
20821        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20822    }
20823
20824    public void setTestPssMode(boolean enabled) {
20825        synchronized (this) {
20826            mTestPssMode = enabled;
20827            if (enabled) {
20828                // Whenever we enable the mode, we want to take a snapshot all of current
20829                // process mem use.
20830                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
20831            }
20832        }
20833    }
20834
20835    /**
20836     * Ask a given process to GC right now.
20837     */
20838    final void performAppGcLocked(ProcessRecord app) {
20839        try {
20840            app.lastRequestedGc = SystemClock.uptimeMillis();
20841            if (app.thread != null) {
20842                if (app.reportLowMemory) {
20843                    app.reportLowMemory = false;
20844                    app.thread.scheduleLowMemory();
20845                } else {
20846                    app.thread.processInBackground();
20847                }
20848            }
20849        } catch (Exception e) {
20850            // whatever.
20851        }
20852    }
20853
20854    /**
20855     * Returns true if things are idle enough to perform GCs.
20856     */
20857    private final boolean canGcNowLocked() {
20858        boolean processingBroadcasts = false;
20859        for (BroadcastQueue q : mBroadcastQueues) {
20860            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
20861                processingBroadcasts = true;
20862            }
20863        }
20864        return !processingBroadcasts
20865                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
20866    }
20867
20868    /**
20869     * Perform GCs on all processes that are waiting for it, but only
20870     * if things are idle.
20871     */
20872    final void performAppGcsLocked() {
20873        final int N = mProcessesToGc.size();
20874        if (N <= 0) {
20875            return;
20876        }
20877        if (canGcNowLocked()) {
20878            while (mProcessesToGc.size() > 0) {
20879                ProcessRecord proc = mProcessesToGc.remove(0);
20880                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
20881                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
20882                            <= SystemClock.uptimeMillis()) {
20883                        // To avoid spamming the system, we will GC processes one
20884                        // at a time, waiting a few seconds between each.
20885                        performAppGcLocked(proc);
20886                        scheduleAppGcsLocked();
20887                        return;
20888                    } else {
20889                        // It hasn't been long enough since we last GCed this
20890                        // process...  put it in the list to wait for its time.
20891                        addProcessToGcListLocked(proc);
20892                        break;
20893                    }
20894                }
20895            }
20896
20897            scheduleAppGcsLocked();
20898        }
20899    }
20900
20901    /**
20902     * If all looks good, perform GCs on all processes waiting for them.
20903     */
20904    final void performAppGcsIfAppropriateLocked() {
20905        if (canGcNowLocked()) {
20906            performAppGcsLocked();
20907            return;
20908        }
20909        // Still not idle, wait some more.
20910        scheduleAppGcsLocked();
20911    }
20912
20913    /**
20914     * Schedule the execution of all pending app GCs.
20915     */
20916    final void scheduleAppGcsLocked() {
20917        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
20918
20919        if (mProcessesToGc.size() > 0) {
20920            // Schedule a GC for the time to the next process.
20921            ProcessRecord proc = mProcessesToGc.get(0);
20922            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
20923
20924            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
20925            long now = SystemClock.uptimeMillis();
20926            if (when < (now+GC_TIMEOUT)) {
20927                when = now + GC_TIMEOUT;
20928            }
20929            mHandler.sendMessageAtTime(msg, when);
20930        }
20931    }
20932
20933    /**
20934     * Add a process to the array of processes waiting to be GCed.  Keeps the
20935     * list in sorted order by the last GC time.  The process can't already be
20936     * on the list.
20937     */
20938    final void addProcessToGcListLocked(ProcessRecord proc) {
20939        boolean added = false;
20940        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
20941            if (mProcessesToGc.get(i).lastRequestedGc <
20942                    proc.lastRequestedGc) {
20943                added = true;
20944                mProcessesToGc.add(i+1, proc);
20945                break;
20946            }
20947        }
20948        if (!added) {
20949            mProcessesToGc.add(0, proc);
20950        }
20951    }
20952
20953    /**
20954     * Set up to ask a process to GC itself.  This will either do it
20955     * immediately, or put it on the list of processes to gc the next
20956     * time things are idle.
20957     */
20958    final void scheduleAppGcLocked(ProcessRecord app) {
20959        long now = SystemClock.uptimeMillis();
20960        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
20961            return;
20962        }
20963        if (!mProcessesToGc.contains(app)) {
20964            addProcessToGcListLocked(app);
20965            scheduleAppGcsLocked();
20966        }
20967    }
20968
20969    final void checkExcessivePowerUsageLocked(boolean doKills) {
20970        updateCpuStatsNow();
20971
20972        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20973        boolean doWakeKills = doKills;
20974        boolean doCpuKills = doKills;
20975        if (mLastPowerCheckRealtime == 0) {
20976            doWakeKills = false;
20977        }
20978        if (mLastPowerCheckUptime == 0) {
20979            doCpuKills = false;
20980        }
20981        if (stats.isScreenOn()) {
20982            doWakeKills = false;
20983        }
20984        final long curRealtime = SystemClock.elapsedRealtime();
20985        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
20986        final long curUptime = SystemClock.uptimeMillis();
20987        final long uptimeSince = curUptime - mLastPowerCheckUptime;
20988        mLastPowerCheckRealtime = curRealtime;
20989        mLastPowerCheckUptime = curUptime;
20990        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
20991            doWakeKills = false;
20992        }
20993        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
20994            doCpuKills = false;
20995        }
20996        int i = mLruProcesses.size();
20997        while (i > 0) {
20998            i--;
20999            ProcessRecord app = mLruProcesses.get(i);
21000            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
21001                long wtime;
21002                synchronized (stats) {
21003                    wtime = stats.getProcessWakeTime(app.info.uid,
21004                            app.pid, curRealtime);
21005                }
21006                long wtimeUsed = wtime - app.lastWakeTime;
21007                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
21008                if (DEBUG_POWER) {
21009                    StringBuilder sb = new StringBuilder(128);
21010                    sb.append("Wake for ");
21011                    app.toShortString(sb);
21012                    sb.append(": over ");
21013                    TimeUtils.formatDuration(realtimeSince, sb);
21014                    sb.append(" used ");
21015                    TimeUtils.formatDuration(wtimeUsed, sb);
21016                    sb.append(" (");
21017                    sb.append((wtimeUsed*100)/realtimeSince);
21018                    sb.append("%)");
21019                    Slog.i(TAG_POWER, sb.toString());
21020                    sb.setLength(0);
21021                    sb.append("CPU for ");
21022                    app.toShortString(sb);
21023                    sb.append(": over ");
21024                    TimeUtils.formatDuration(uptimeSince, sb);
21025                    sb.append(" used ");
21026                    TimeUtils.formatDuration(cputimeUsed, sb);
21027                    sb.append(" (");
21028                    sb.append((cputimeUsed*100)/uptimeSince);
21029                    sb.append("%)");
21030                    Slog.i(TAG_POWER, sb.toString());
21031                }
21032                // If a process has held a wake lock for more
21033                // than 50% of the time during this period,
21034                // that sounds bad.  Kill!
21035                if (doWakeKills && realtimeSince > 0
21036                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
21037                    synchronized (stats) {
21038                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
21039                                realtimeSince, wtimeUsed);
21040                    }
21041                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
21042                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
21043                } else if (doCpuKills && uptimeSince > 0
21044                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
21045                    synchronized (stats) {
21046                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
21047                                uptimeSince, cputimeUsed);
21048                    }
21049                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
21050                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
21051                } else {
21052                    app.lastWakeTime = wtime;
21053                    app.lastCpuTime = app.curCpuTime;
21054                }
21055            }
21056        }
21057    }
21058
21059    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
21060            long nowElapsed) {
21061        boolean success = true;
21062
21063        if (app.curRawAdj != app.setRawAdj) {
21064            app.setRawAdj = app.curRawAdj;
21065        }
21066
21067        int changes = 0;
21068
21069        if (app.curAdj != app.setAdj) {
21070            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
21071            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21072                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
21073                    + app.adjType);
21074            app.setAdj = app.curAdj;
21075            app.verifiedAdj = ProcessList.INVALID_ADJ;
21076        }
21077
21078        if (app.setSchedGroup != app.curSchedGroup) {
21079            int oldSchedGroup = app.setSchedGroup;
21080            app.setSchedGroup = app.curSchedGroup;
21081            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21082                    "Setting sched group of " + app.processName
21083                    + " to " + app.curSchedGroup);
21084            if (app.waitingToKill != null && app.curReceivers.isEmpty()
21085                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
21086                app.kill(app.waitingToKill, true);
21087                success = false;
21088            } else {
21089                int processGroup;
21090                switch (app.curSchedGroup) {
21091                    case ProcessList.SCHED_GROUP_BACKGROUND:
21092                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
21093                        break;
21094                    case ProcessList.SCHED_GROUP_TOP_APP:
21095                    case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
21096                        processGroup = Process.THREAD_GROUP_TOP_APP;
21097                        break;
21098                    default:
21099                        processGroup = Process.THREAD_GROUP_DEFAULT;
21100                        break;
21101                }
21102                long oldId = Binder.clearCallingIdentity();
21103                try {
21104                    Process.setProcessGroup(app.pid, processGroup);
21105                    if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
21106                        // do nothing if we already switched to RT
21107                        if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
21108                            // Switch VR thread for app to SCHED_FIFO
21109                            if (mInVrMode && app.vrThreadTid != 0) {
21110                                try {
21111                                    Process.setThreadScheduler(app.vrThreadTid,
21112                                        Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
21113                                } catch (IllegalArgumentException e) {
21114                                    // thread died, ignore
21115                                }
21116                            }
21117                            if (mUseFifoUiScheduling) {
21118                                // Switch UI pipeline for app to SCHED_FIFO
21119                                app.savedPriority = Process.getThreadPriority(app.pid);
21120                                try {
21121                                    Process.setThreadScheduler(app.pid,
21122                                        Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
21123                                } catch (IllegalArgumentException e) {
21124                                    // thread died, ignore
21125                                }
21126                                if (app.renderThreadTid != 0) {
21127                                    try {
21128                                        Process.setThreadScheduler(app.renderThreadTid,
21129                                            Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
21130                                    } catch (IllegalArgumentException e) {
21131                                        // thread died, ignore
21132                                    }
21133                                    if (DEBUG_OOM_ADJ) {
21134                                        Slog.d("UI_FIFO", "Set RenderThread (TID " +
21135                                            app.renderThreadTid + ") to FIFO");
21136                                    }
21137                                } else {
21138                                    if (DEBUG_OOM_ADJ) {
21139                                        Slog.d("UI_FIFO", "Not setting RenderThread TID");
21140                                    }
21141                                }
21142                            } else {
21143                                // Boost priority for top app UI and render threads
21144                                Process.setThreadPriority(app.pid, -10);
21145                                if (app.renderThreadTid != 0) {
21146                                    try {
21147                                        Process.setThreadPriority(app.renderThreadTid, -10);
21148                                    } catch (IllegalArgumentException e) {
21149                                        // thread died, ignore
21150                                    }
21151                                }
21152                            }
21153                        }
21154                    } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
21155                               app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
21156                        // Reset VR thread to SCHED_OTHER
21157                        // Safe to do even if we're not in VR mode
21158                        if (app.vrThreadTid != 0) {
21159                            Process.setThreadScheduler(app.vrThreadTid, Process.SCHED_OTHER, 0);
21160                        }
21161                        if (mUseFifoUiScheduling) {
21162                            // Reset UI pipeline to SCHED_OTHER
21163                            Process.setThreadScheduler(app.pid, Process.SCHED_OTHER, 0);
21164                            Process.setThreadPriority(app.pid, app.savedPriority);
21165                            if (app.renderThreadTid != 0) {
21166                                Process.setThreadScheduler(app.renderThreadTid,
21167                                    Process.SCHED_OTHER, 0);
21168                                Process.setThreadPriority(app.renderThreadTid, -4);
21169                            }
21170                        } else {
21171                            // Reset priority for top app UI and render threads
21172                            Process.setThreadPriority(app.pid, 0);
21173                            if (app.renderThreadTid != 0) {
21174                                Process.setThreadPriority(app.renderThreadTid, 0);
21175                            }
21176                        }
21177                    }
21178                } catch (Exception e) {
21179                    Slog.w(TAG, "Failed setting process group of " + app.pid
21180                            + " to " + app.curSchedGroup);
21181                    e.printStackTrace();
21182                } finally {
21183                    Binder.restoreCallingIdentity(oldId);
21184                }
21185            }
21186        }
21187        if (app.repForegroundActivities != app.foregroundActivities) {
21188            app.repForegroundActivities = app.foregroundActivities;
21189            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
21190        }
21191        if (app.repProcState != app.curProcState) {
21192            app.repProcState = app.curProcState;
21193            if (app.thread != null) {
21194                try {
21195                    if (false) {
21196                        //RuntimeException h = new RuntimeException("here");
21197                        Slog.i(TAG, "Sending new process state " + app.repProcState
21198                                + " to " + app /*, h*/);
21199                    }
21200                    app.thread.setProcessState(app.repProcState);
21201                } catch (RemoteException e) {
21202                }
21203            }
21204        }
21205        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
21206                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
21207            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
21208                // Experimental code to more aggressively collect pss while
21209                // running test...  the problem is that this tends to collect
21210                // the data right when a process is transitioning between process
21211                // states, which well tend to give noisy data.
21212                long start = SystemClock.uptimeMillis();
21213                long pss = Debug.getPss(app.pid, mTmpLong, null);
21214                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
21215                mPendingPssProcesses.remove(app);
21216                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
21217                        + " to " + app.curProcState + ": "
21218                        + (SystemClock.uptimeMillis()-start) + "ms");
21219            }
21220            app.lastStateTime = now;
21221            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
21222                    mTestPssMode, isSleepingLocked(), now);
21223            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
21224                    + ProcessList.makeProcStateString(app.setProcState) + " to "
21225                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
21226                    + (app.nextPssTime-now) + ": " + app);
21227        } else {
21228            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
21229                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
21230                    mTestPssMode)))) {
21231                requestPssLocked(app, app.setProcState);
21232                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
21233                        mTestPssMode, isSleepingLocked(), now);
21234            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
21235                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
21236        }
21237        if (app.setProcState != app.curProcState) {
21238            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21239                    "Proc state change of " + app.processName
21240                            + " to " + app.curProcState);
21241            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
21242            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
21243            if (setImportant && !curImportant) {
21244                // This app is no longer something we consider important enough to allow to
21245                // use arbitrary amounts of battery power.  Note
21246                // its current wake lock time to later know to kill it if
21247                // it is not behaving well.
21248                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
21249                synchronized (stats) {
21250                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
21251                            app.pid, nowElapsed);
21252                }
21253                app.lastCpuTime = app.curCpuTime;
21254
21255            }
21256            // Inform UsageStats of important process state change
21257            // Must be called before updating setProcState
21258            maybeUpdateUsageStatsLocked(app, nowElapsed);
21259
21260            app.setProcState = app.curProcState;
21261            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
21262                app.notCachedSinceIdle = false;
21263            }
21264            if (!doingAll) {
21265                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
21266            } else {
21267                app.procStateChanged = true;
21268            }
21269        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
21270                > USAGE_STATS_INTERACTION_INTERVAL) {
21271            // For apps that sit around for a long time in the interactive state, we need
21272            // to report this at least once a day so they don't go idle.
21273            maybeUpdateUsageStatsLocked(app, nowElapsed);
21274        }
21275
21276        if (changes != 0) {
21277            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21278                    "Changes in " + app + ": " + changes);
21279            int i = mPendingProcessChanges.size()-1;
21280            ProcessChangeItem item = null;
21281            while (i >= 0) {
21282                item = mPendingProcessChanges.get(i);
21283                if (item.pid == app.pid) {
21284                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21285                            "Re-using existing item: " + item);
21286                    break;
21287                }
21288                i--;
21289            }
21290            if (i < 0) {
21291                // No existing item in pending changes; need a new one.
21292                final int NA = mAvailProcessChanges.size();
21293                if (NA > 0) {
21294                    item = mAvailProcessChanges.remove(NA-1);
21295                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21296                            "Retrieving available item: " + item);
21297                } else {
21298                    item = new ProcessChangeItem();
21299                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21300                            "Allocating new item: " + item);
21301                }
21302                item.changes = 0;
21303                item.pid = app.pid;
21304                item.uid = app.info.uid;
21305                if (mPendingProcessChanges.size() == 0) {
21306                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21307                            "*** Enqueueing dispatch processes changed!");
21308                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
21309                }
21310                mPendingProcessChanges.add(item);
21311            }
21312            item.changes |= changes;
21313            item.foregroundActivities = app.repForegroundActivities;
21314            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21315                    "Item " + Integer.toHexString(System.identityHashCode(item))
21316                    + " " + app.toShortString() + ": changes=" + item.changes
21317                    + " foreground=" + item.foregroundActivities
21318                    + " type=" + app.adjType + " source=" + app.adjSource
21319                    + " target=" + app.adjTarget);
21320        }
21321
21322        return success;
21323    }
21324
21325    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
21326        final UidRecord.ChangeItem pendingChange;
21327        if (uidRec == null || uidRec.pendingChange == null) {
21328            if (mPendingUidChanges.size() == 0) {
21329                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21330                        "*** Enqueueing dispatch uid changed!");
21331                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
21332            }
21333            final int NA = mAvailUidChanges.size();
21334            if (NA > 0) {
21335                pendingChange = mAvailUidChanges.remove(NA-1);
21336                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21337                        "Retrieving available item: " + pendingChange);
21338            } else {
21339                pendingChange = new UidRecord.ChangeItem();
21340                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21341                        "Allocating new item: " + pendingChange);
21342            }
21343            if (uidRec != null) {
21344                uidRec.pendingChange = pendingChange;
21345                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
21346                    // If this uid is going away, and we haven't yet reported it is gone,
21347                    // then do so now.
21348                    change = UidRecord.CHANGE_GONE_IDLE;
21349                }
21350            } else if (uid < 0) {
21351                throw new IllegalArgumentException("No UidRecord or uid");
21352            }
21353            pendingChange.uidRecord = uidRec;
21354            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
21355            mPendingUidChanges.add(pendingChange);
21356        } else {
21357            pendingChange = uidRec.pendingChange;
21358            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
21359                change = UidRecord.CHANGE_GONE_IDLE;
21360            }
21361        }
21362        pendingChange.change = change;
21363        pendingChange.processState = uidRec != null
21364                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
21365        pendingChange.ephemeral = uidRec.ephemeral;
21366
21367        // Directly update the power manager, since we sit on top of it and it is critical
21368        // it be kept in sync (so wake locks will be held as soon as appropriate).
21369        if (mLocalPowerManager != null) {
21370            switch (change) {
21371                case UidRecord.CHANGE_GONE:
21372                case UidRecord.CHANGE_GONE_IDLE:
21373                    mLocalPowerManager.uidGone(pendingChange.uid);
21374                    break;
21375                case UidRecord.CHANGE_IDLE:
21376                    mLocalPowerManager.uidIdle(pendingChange.uid);
21377                    break;
21378                case UidRecord.CHANGE_ACTIVE:
21379                    mLocalPowerManager.uidActive(pendingChange.uid);
21380                    break;
21381                default:
21382                    mLocalPowerManager.updateUidProcState(pendingChange.uid,
21383                            pendingChange.processState);
21384                    break;
21385            }
21386        }
21387    }
21388
21389    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
21390            String authority) {
21391        if (app == null) return;
21392        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
21393            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
21394            if (userState == null) return;
21395            final long now = SystemClock.elapsedRealtime();
21396            Long lastReported = userState.mProviderLastReportedFg.get(authority);
21397            if (lastReported == null || lastReported < now - 60 * 1000L) {
21398                if (mSystemReady) {
21399                    // Cannot touch the user stats if not system ready
21400                    mUsageStatsService.reportContentProviderUsage(
21401                            authority, providerPkgName, app.userId);
21402                }
21403                userState.mProviderLastReportedFg.put(authority, now);
21404            }
21405        }
21406    }
21407
21408    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
21409        if (DEBUG_USAGE_STATS) {
21410            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
21411                    + "] state changes: old = " + app.setProcState + ", new = "
21412                    + app.curProcState);
21413        }
21414        if (mUsageStatsService == null) {
21415            return;
21416        }
21417        boolean isInteraction;
21418        // To avoid some abuse patterns, we are going to be careful about what we consider
21419        // to be an app interaction.  Being the top activity doesn't count while the display
21420        // is sleeping, nor do short foreground services.
21421        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
21422            isInteraction = true;
21423            app.fgInteractionTime = 0;
21424        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
21425            if (app.fgInteractionTime == 0) {
21426                app.fgInteractionTime = nowElapsed;
21427                isInteraction = false;
21428            } else {
21429                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
21430            }
21431        } else {
21432            // If the app was being forced to the foreground, by say a Toast, then
21433            // no need to treat it as an interaction
21434            isInteraction = app.forcingToForeground == null
21435                    && app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21436            app.fgInteractionTime = 0;
21437        }
21438        if (isInteraction && (!app.reportedInteraction
21439                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
21440            app.interactionEventTime = nowElapsed;
21441            String[] packages = app.getPackageList();
21442            if (packages != null) {
21443                for (int i = 0; i < packages.length; i++) {
21444                    mUsageStatsService.reportEvent(packages[i], app.userId,
21445                            UsageEvents.Event.SYSTEM_INTERACTION);
21446                }
21447            }
21448        }
21449        app.reportedInteraction = isInteraction;
21450        if (!isInteraction) {
21451            app.interactionEventTime = 0;
21452        }
21453    }
21454
21455    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
21456        if (proc.thread != null) {
21457            if (proc.baseProcessTracker != null) {
21458                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
21459            }
21460        }
21461    }
21462
21463    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
21464            ProcessRecord TOP_APP, boolean doingAll, long now) {
21465        if (app.thread == null) {
21466            return false;
21467        }
21468
21469        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
21470
21471        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
21472    }
21473
21474    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
21475            boolean oomAdj) {
21476        if (isForeground != proc.foregroundServices) {
21477            proc.foregroundServices = isForeground;
21478            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
21479                    proc.info.uid);
21480            if (isForeground) {
21481                if (curProcs == null) {
21482                    curProcs = new ArrayList<ProcessRecord>();
21483                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
21484                }
21485                if (!curProcs.contains(proc)) {
21486                    curProcs.add(proc);
21487                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
21488                            proc.info.packageName, proc.info.uid);
21489                }
21490            } else {
21491                if (curProcs != null) {
21492                    if (curProcs.remove(proc)) {
21493                        mBatteryStatsService.noteEvent(
21494                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
21495                                proc.info.packageName, proc.info.uid);
21496                        if (curProcs.size() <= 0) {
21497                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
21498                        }
21499                    }
21500                }
21501            }
21502            if (oomAdj) {
21503                updateOomAdjLocked();
21504            }
21505        }
21506    }
21507
21508    private final ActivityRecord resumedAppLocked() {
21509        ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
21510        String pkg;
21511        int uid;
21512        if (act != null) {
21513            pkg = act.packageName;
21514            uid = act.info.applicationInfo.uid;
21515        } else {
21516            pkg = null;
21517            uid = -1;
21518        }
21519        // Has the UID or resumed package name changed?
21520        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
21521                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
21522            if (mCurResumedPackage != null) {
21523                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
21524                        mCurResumedPackage, mCurResumedUid);
21525            }
21526            mCurResumedPackage = pkg;
21527            mCurResumedUid = uid;
21528            if (mCurResumedPackage != null) {
21529                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
21530                        mCurResumedPackage, mCurResumedUid);
21531            }
21532        }
21533        return act;
21534    }
21535
21536    final boolean updateOomAdjLocked(ProcessRecord app) {
21537        final ActivityRecord TOP_ACT = resumedAppLocked();
21538        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
21539        final boolean wasCached = app.cached;
21540
21541        mAdjSeq++;
21542
21543        // This is the desired cached adjusment we want to tell it to use.
21544        // If our app is currently cached, we know it, and that is it.  Otherwise,
21545        // we don't know it yet, and it needs to now be cached we will then
21546        // need to do a complete oom adj.
21547        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
21548                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
21549        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
21550                SystemClock.uptimeMillis());
21551        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
21552            // Changed to/from cached state, so apps after it in the LRU
21553            // list may also be changed.
21554            updateOomAdjLocked();
21555        }
21556        return success;
21557    }
21558
21559    final void updateOomAdjLocked() {
21560        final ActivityRecord TOP_ACT = resumedAppLocked();
21561        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
21562        final long now = SystemClock.uptimeMillis();
21563        final long nowElapsed = SystemClock.elapsedRealtime();
21564        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
21565        final int N = mLruProcesses.size();
21566
21567        if (false) {
21568            RuntimeException e = new RuntimeException();
21569            e.fillInStackTrace();
21570            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
21571        }
21572
21573        // Reset state in all uid records.
21574        for (int i=mActiveUids.size()-1; i>=0; i--) {
21575            final UidRecord uidRec = mActiveUids.valueAt(i);
21576            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21577                    "Starting update of " + uidRec);
21578            uidRec.reset();
21579        }
21580
21581        mStackSupervisor.rankTaskLayersIfNeeded();
21582
21583        mAdjSeq++;
21584        mNewNumServiceProcs = 0;
21585        mNewNumAServiceProcs = 0;
21586
21587        final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
21588        final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit;
21589
21590        // Let's determine how many processes we have running vs.
21591        // how many slots we have for background processes; we may want
21592        // to put multiple processes in a slot of there are enough of
21593        // them.
21594        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
21595                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
21596        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
21597        if (numEmptyProcs > cachedProcessLimit) {
21598            // If there are more empty processes than our limit on cached
21599            // processes, then use the cached process limit for the factor.
21600            // This ensures that the really old empty processes get pushed
21601            // down to the bottom, so if we are running low on memory we will
21602            // have a better chance at keeping around more cached processes
21603            // instead of a gazillion empty processes.
21604            numEmptyProcs = cachedProcessLimit;
21605        }
21606        int emptyFactor = numEmptyProcs/numSlots;
21607        if (emptyFactor < 1) emptyFactor = 1;
21608        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
21609        if (cachedFactor < 1) cachedFactor = 1;
21610        int stepCached = 0;
21611        int stepEmpty = 0;
21612        int numCached = 0;
21613        int numEmpty = 0;
21614        int numTrimming = 0;
21615
21616        mNumNonCachedProcs = 0;
21617        mNumCachedHiddenProcs = 0;
21618
21619        // First update the OOM adjustment for each of the
21620        // application processes based on their current state.
21621        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
21622        int nextCachedAdj = curCachedAdj+1;
21623        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
21624        int nextEmptyAdj = curEmptyAdj+2;
21625        for (int i=N-1; i>=0; i--) {
21626            ProcessRecord app = mLruProcesses.get(i);
21627            if (!app.killedByAm && app.thread != null) {
21628                app.procStateChanged = false;
21629                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
21630
21631                // If we haven't yet assigned the final cached adj
21632                // to the process, do that now.
21633                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
21634                    switch (app.curProcState) {
21635                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
21636                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
21637                            // This process is a cached process holding activities...
21638                            // assign it the next cached value for that type, and then
21639                            // step that cached level.
21640                            app.curRawAdj = curCachedAdj;
21641                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
21642                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
21643                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
21644                                    + ")");
21645                            if (curCachedAdj != nextCachedAdj) {
21646                                stepCached++;
21647                                if (stepCached >= cachedFactor) {
21648                                    stepCached = 0;
21649                                    curCachedAdj = nextCachedAdj;
21650                                    nextCachedAdj += 2;
21651                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
21652                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
21653                                    }
21654                                }
21655                            }
21656                            break;
21657                        default:
21658                            // For everything else, assign next empty cached process
21659                            // level and bump that up.  Note that this means that
21660                            // long-running services that have dropped down to the
21661                            // cached level will be treated as empty (since their process
21662                            // state is still as a service), which is what we want.
21663                            app.curRawAdj = curEmptyAdj;
21664                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
21665                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
21666                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
21667                                    + ")");
21668                            if (curEmptyAdj != nextEmptyAdj) {
21669                                stepEmpty++;
21670                                if (stepEmpty >= emptyFactor) {
21671                                    stepEmpty = 0;
21672                                    curEmptyAdj = nextEmptyAdj;
21673                                    nextEmptyAdj += 2;
21674                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
21675                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
21676                                    }
21677                                }
21678                            }
21679                            break;
21680                    }
21681                }
21682
21683                applyOomAdjLocked(app, true, now, nowElapsed);
21684
21685                // Count the number of process types.
21686                switch (app.curProcState) {
21687                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
21688                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
21689                        mNumCachedHiddenProcs++;
21690                        numCached++;
21691                        if (numCached > cachedProcessLimit) {
21692                            app.kill("cached #" + numCached, true);
21693                        }
21694                        break;
21695                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
21696                        if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
21697                                && app.lastActivityTime < oldTime) {
21698                            app.kill("empty for "
21699                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
21700                                    / 1000) + "s", true);
21701                        } else {
21702                            numEmpty++;
21703                            if (numEmpty > emptyProcessLimit) {
21704                                app.kill("empty #" + numEmpty, true);
21705                            }
21706                        }
21707                        break;
21708                    default:
21709                        mNumNonCachedProcs++;
21710                        break;
21711                }
21712
21713                if (app.isolated && app.services.size() <= 0) {
21714                    // If this is an isolated process, and there are no
21715                    // services running in it, then the process is no longer
21716                    // needed.  We agressively kill these because we can by
21717                    // definition not re-use the same process again, and it is
21718                    // good to avoid having whatever code was running in them
21719                    // left sitting around after no longer needed.
21720                    app.kill("isolated not needed", true);
21721                } else {
21722                    // Keeping this process, update its uid.
21723                    final UidRecord uidRec = app.uidRecord;
21724                    if (uidRec != null) {
21725                        uidRec.ephemeral = app.info.isInstantApp();
21726                        if (uidRec.curProcState > app.curProcState) {
21727                            uidRec.curProcState = app.curProcState;
21728                        }
21729                    }
21730                }
21731
21732                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21733                        && !app.killedByAm) {
21734                    numTrimming++;
21735                }
21736            }
21737        }
21738
21739        mNumServiceProcs = mNewNumServiceProcs;
21740
21741        // Now determine the memory trimming level of background processes.
21742        // Unfortunately we need to start at the back of the list to do this
21743        // properly.  We only do this if the number of background apps we
21744        // are managing to keep around is less than half the maximum we desire;
21745        // if we are keeping a good number around, we'll let them use whatever
21746        // memory they want.
21747        final int numCachedAndEmpty = numCached + numEmpty;
21748        int memFactor;
21749        if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
21750                && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
21751            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
21752                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
21753            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
21754                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
21755            } else {
21756                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
21757            }
21758        } else {
21759            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
21760        }
21761        // We always allow the memory level to go up (better).  We only allow it to go
21762        // down if we are in a state where that is allowed, *and* the total number of processes
21763        // has gone down since last time.
21764        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
21765                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
21766                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
21767        if (memFactor > mLastMemoryLevel) {
21768            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
21769                memFactor = mLastMemoryLevel;
21770                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
21771            }
21772        }
21773        if (memFactor != mLastMemoryLevel) {
21774            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
21775        }
21776        mLastMemoryLevel = memFactor;
21777        mLastNumProcesses = mLruProcesses.size();
21778        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
21779        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
21780        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
21781            if (mLowRamStartTime == 0) {
21782                mLowRamStartTime = now;
21783            }
21784            int step = 0;
21785            int fgTrimLevel;
21786            switch (memFactor) {
21787                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
21788                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
21789                    break;
21790                case ProcessStats.ADJ_MEM_FACTOR_LOW:
21791                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
21792                    break;
21793                default:
21794                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
21795                    break;
21796            }
21797            int factor = numTrimming/3;
21798            int minFactor = 2;
21799            if (mHomeProcess != null) minFactor++;
21800            if (mPreviousProcess != null) minFactor++;
21801            if (factor < minFactor) factor = minFactor;
21802            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
21803            for (int i=N-1; i>=0; i--) {
21804                ProcessRecord app = mLruProcesses.get(i);
21805                if (allChanged || app.procStateChanged) {
21806                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
21807                    app.procStateChanged = false;
21808                }
21809                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21810                        && !app.killedByAm) {
21811                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
21812                        try {
21813                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21814                                    "Trimming memory of " + app.processName + " to " + curLevel);
21815                            app.thread.scheduleTrimMemory(curLevel);
21816                        } catch (RemoteException e) {
21817                        }
21818                        if (false) {
21819                            // For now we won't do this; our memory trimming seems
21820                            // to be good enough at this point that destroying
21821                            // activities causes more harm than good.
21822                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
21823                                    && app != mHomeProcess && app != mPreviousProcess) {
21824                                // Need to do this on its own message because the stack may not
21825                                // be in a consistent state at this point.
21826                                // For these apps we will also finish their activities
21827                                // to help them free memory.
21828                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
21829                            }
21830                        }
21831                    }
21832                    app.trimMemoryLevel = curLevel;
21833                    step++;
21834                    if (step >= factor) {
21835                        step = 0;
21836                        switch (curLevel) {
21837                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
21838                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
21839                                break;
21840                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
21841                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21842                                break;
21843                        }
21844                    }
21845                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21846                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
21847                            && app.thread != null) {
21848                        try {
21849                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21850                                    "Trimming memory of heavy-weight " + app.processName
21851                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21852                            app.thread.scheduleTrimMemory(
21853                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21854                        } catch (RemoteException e) {
21855                        }
21856                    }
21857                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21858                } else {
21859                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21860                            || app.systemNoUi) && app.pendingUiClean) {
21861                        // If this application is now in the background and it
21862                        // had done UI, then give it the special trim level to
21863                        // have it free UI resources.
21864                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
21865                        if (app.trimMemoryLevel < level && app.thread != null) {
21866                            try {
21867                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21868                                        "Trimming memory of bg-ui " + app.processName
21869                                        + " to " + level);
21870                                app.thread.scheduleTrimMemory(level);
21871                            } catch (RemoteException e) {
21872                            }
21873                        }
21874                        app.pendingUiClean = false;
21875                    }
21876                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
21877                        try {
21878                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21879                                    "Trimming memory of fg " + app.processName
21880                                    + " to " + fgTrimLevel);
21881                            app.thread.scheduleTrimMemory(fgTrimLevel);
21882                        } catch (RemoteException e) {
21883                        }
21884                    }
21885                    app.trimMemoryLevel = fgTrimLevel;
21886                }
21887            }
21888        } else {
21889            if (mLowRamStartTime != 0) {
21890                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
21891                mLowRamStartTime = 0;
21892            }
21893            for (int i=N-1; i>=0; i--) {
21894                ProcessRecord app = mLruProcesses.get(i);
21895                if (allChanged || app.procStateChanged) {
21896                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
21897                    app.procStateChanged = false;
21898                }
21899                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21900                        || app.systemNoUi) && app.pendingUiClean) {
21901                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
21902                            && app.thread != null) {
21903                        try {
21904                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21905                                    "Trimming memory of ui hidden " + app.processName
21906                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21907                            app.thread.scheduleTrimMemory(
21908                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21909                        } catch (RemoteException e) {
21910                        }
21911                    }
21912                    app.pendingUiClean = false;
21913                }
21914                app.trimMemoryLevel = 0;
21915            }
21916        }
21917
21918        if (mAlwaysFinishActivities) {
21919            // Need to do this on its own message because the stack may not
21920            // be in a consistent state at this point.
21921            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
21922        }
21923
21924        if (allChanged) {
21925            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
21926        }
21927
21928        // Update from any uid changes.
21929        if (mLocalPowerManager != null) {
21930            mLocalPowerManager.startUidChanges();
21931        }
21932        for (int i=mActiveUids.size()-1; i>=0; i--) {
21933            final UidRecord uidRec = mActiveUids.valueAt(i);
21934            int uidChange = UidRecord.CHANGE_PROCSTATE;
21935            if (uidRec.setProcState != uidRec.curProcState
21936                    || uidRec.setWhitelist != uidRec.curWhitelist) {
21937                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21938                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
21939                        + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist
21940                        + " to " + uidRec.curWhitelist);
21941                if (ActivityManager.isProcStateBackground(uidRec.curProcState)
21942                        && !uidRec.curWhitelist) {
21943                    // UID is now in the background (and not on the temp whitelist).  Was it
21944                    // previously in the foreground (or on the temp whitelist)?
21945                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)
21946                            || uidRec.setWhitelist) {
21947                        uidRec.lastBackgroundTime = nowElapsed;
21948                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
21949                            // Note: the background settle time is in elapsed realtime, while
21950                            // the handler time base is uptime.  All this means is that we may
21951                            // stop background uids later than we had intended, but that only
21952                            // happens because the device was sleeping so we are okay anyway.
21953                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
21954                        }
21955                    }
21956                } else {
21957                    if (uidRec.idle) {
21958                        uidChange = UidRecord.CHANGE_ACTIVE;
21959                        uidRec.idle = false;
21960                    }
21961                    uidRec.lastBackgroundTime = 0;
21962                }
21963                uidRec.setProcState = uidRec.curProcState;
21964                uidRec.setWhitelist = uidRec.curWhitelist;
21965                enqueueUidChangeLocked(uidRec, -1, uidChange);
21966                noteUidProcessState(uidRec.uid, uidRec.curProcState);
21967            }
21968        }
21969        if (mLocalPowerManager != null) {
21970            mLocalPowerManager.finishUidChanges();
21971        }
21972
21973        if (mProcessStats.shouldWriteNowLocked(now)) {
21974            mHandler.post(new Runnable() {
21975                @Override public void run() {
21976                    synchronized (ActivityManagerService.this) {
21977                        mProcessStats.writeStateAsyncLocked();
21978                    }
21979                }
21980            });
21981        }
21982
21983        if (DEBUG_OOM_ADJ) {
21984            final long duration = SystemClock.uptimeMillis() - now;
21985            if (false) {
21986                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
21987                        new RuntimeException("here").fillInStackTrace());
21988            } else {
21989                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
21990            }
21991        }
21992    }
21993
21994    @Override
21995    public void makePackageIdle(String packageName, int userId) {
21996        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
21997                != PackageManager.PERMISSION_GRANTED) {
21998            String msg = "Permission Denial: makePackageIdle() from pid="
21999                    + Binder.getCallingPid()
22000                    + ", uid=" + Binder.getCallingUid()
22001                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
22002            Slog.w(TAG, msg);
22003            throw new SecurityException(msg);
22004        }
22005        final int callingPid = Binder.getCallingPid();
22006        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
22007                userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
22008        long callingId = Binder.clearCallingIdentity();
22009        synchronized(this) {
22010            try {
22011                IPackageManager pm = AppGlobals.getPackageManager();
22012                int pkgUid = -1;
22013                try {
22014                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
22015                            | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
22016                } catch (RemoteException e) {
22017                }
22018                if (pkgUid == -1) {
22019                    throw new IllegalArgumentException("Unknown package name " + packageName);
22020                }
22021
22022                if (mLocalPowerManager != null) {
22023                    mLocalPowerManager.startUidChanges();
22024                }
22025                final int appId = UserHandle.getAppId(pkgUid);
22026                final int N = mActiveUids.size();
22027                for (int i=N-1; i>=0; i--) {
22028                    final UidRecord uidRec = mActiveUids.valueAt(i);
22029                    final long bgTime = uidRec.lastBackgroundTime;
22030                    if (bgTime > 0 && !uidRec.idle) {
22031                        if (UserHandle.getAppId(uidRec.uid) == appId) {
22032                            if (userId == UserHandle.USER_ALL ||
22033                                    userId == UserHandle.getUserId(uidRec.uid)) {
22034                                uidRec.idle = true;
22035                                Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
22036                                        + " from package " + packageName + " user " + userId);
22037                                doStopUidLocked(uidRec.uid, uidRec);
22038                            }
22039                        }
22040                    }
22041                }
22042            } finally {
22043                if (mLocalPowerManager != null) {
22044                    mLocalPowerManager.finishUidChanges();
22045                }
22046                Binder.restoreCallingIdentity(callingId);
22047            }
22048        }
22049    }
22050
22051    final void idleUids() {
22052        synchronized (this) {
22053            final int N = mActiveUids.size();
22054            if (N <= 0) {
22055                return;
22056            }
22057            final long nowElapsed = SystemClock.elapsedRealtime();
22058            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
22059            long nextTime = 0;
22060            if (mLocalPowerManager != null) {
22061                mLocalPowerManager.startUidChanges();
22062            }
22063            for (int i=N-1; i>=0; i--) {
22064                final UidRecord uidRec = mActiveUids.valueAt(i);
22065                final long bgTime = uidRec.lastBackgroundTime;
22066                if (bgTime > 0 && !uidRec.idle) {
22067                    if (bgTime <= maxBgTime) {
22068                        uidRec.idle = true;
22069                        doStopUidLocked(uidRec.uid, uidRec);
22070                    } else {
22071                        if (nextTime == 0 || nextTime > bgTime) {
22072                            nextTime = bgTime;
22073                        }
22074                    }
22075                }
22076            }
22077            if (mLocalPowerManager != null) {
22078                mLocalPowerManager.finishUidChanges();
22079            }
22080            if (nextTime > 0) {
22081                mHandler.removeMessages(IDLE_UIDS_MSG);
22082                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
22083                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
22084            }
22085        }
22086    }
22087
22088    final void runInBackgroundDisabled(int uid) {
22089        synchronized (this) {
22090            UidRecord uidRec = mActiveUids.get(uid);
22091            if (uidRec != null) {
22092                // This uid is actually running...  should it be considered background now?
22093                if (uidRec.idle) {
22094                    doStopUidLocked(uidRec.uid, uidRec);
22095                }
22096            } else {
22097                // This uid isn't actually running...  still send a report about it being "stopped".
22098                doStopUidLocked(uid, null);
22099            }
22100        }
22101    }
22102
22103    final void doStopUidLocked(int uid, final UidRecord uidRec) {
22104        mServices.stopInBackgroundLocked(uid);
22105        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
22106    }
22107
22108    final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) {
22109        boolean changed = false;
22110        for (int i=mActiveUids.size()-1; i>=0; i--) {
22111            final UidRecord uidRec = mActiveUids.valueAt(i);
22112            if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) {
22113                uidRec.curWhitelist = onWhitelist;
22114                changed = true;
22115            }
22116        }
22117        if (changed) {
22118            updateOomAdjLocked();
22119        }
22120    }
22121
22122    final void trimApplications() {
22123        synchronized (this) {
22124            int i;
22125
22126            // First remove any unused application processes whose package
22127            // has been removed.
22128            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
22129                final ProcessRecord app = mRemovedProcesses.get(i);
22130                if (app.activities.size() == 0
22131                        && app.curReceivers.isEmpty() && app.services.size() == 0) {
22132                    Slog.i(
22133                        TAG, "Exiting empty application process "
22134                        + app.toShortString() + " ("
22135                        + (app.thread != null ? app.thread.asBinder() : null)
22136                        + ")\n");
22137                    if (app.pid > 0 && app.pid != MY_PID) {
22138                        app.kill("empty", false);
22139                    } else {
22140                        try {
22141                            app.thread.scheduleExit();
22142                        } catch (Exception e) {
22143                            // Ignore exceptions.
22144                        }
22145                    }
22146                    cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
22147                    mRemovedProcesses.remove(i);
22148
22149                    if (app.persistent) {
22150                        addAppLocked(app.info, null, false, null /* ABI override */);
22151                    }
22152                }
22153            }
22154
22155            // Now update the oom adj for all processes.
22156            updateOomAdjLocked();
22157        }
22158    }
22159
22160    /** This method sends the specified signal to each of the persistent apps */
22161    public void signalPersistentProcesses(int sig) throws RemoteException {
22162        if (sig != Process.SIGNAL_USR1) {
22163            throw new SecurityException("Only SIGNAL_USR1 is allowed");
22164        }
22165
22166        synchronized (this) {
22167            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
22168                    != PackageManager.PERMISSION_GRANTED) {
22169                throw new SecurityException("Requires permission "
22170                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
22171            }
22172
22173            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
22174                ProcessRecord r = mLruProcesses.get(i);
22175                if (r.thread != null && r.persistent) {
22176                    Process.sendSignal(r.pid, sig);
22177                }
22178            }
22179        }
22180    }
22181
22182    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
22183        if (proc == null || proc == mProfileProc) {
22184            proc = mProfileProc;
22185            profileType = mProfileType;
22186            clearProfilerLocked();
22187        }
22188        if (proc == null) {
22189            return;
22190        }
22191        try {
22192            proc.thread.profilerControl(false, null, profileType);
22193        } catch (RemoteException e) {
22194            throw new IllegalStateException("Process disappeared");
22195        }
22196    }
22197
22198    private void clearProfilerLocked() {
22199        if (mProfileFd != null) {
22200            try {
22201                mProfileFd.close();
22202            } catch (IOException e) {
22203            }
22204        }
22205        mProfileApp = null;
22206        mProfileProc = null;
22207        mProfileFile = null;
22208        mProfileType = 0;
22209        mAutoStopProfiler = false;
22210        mStreamingOutput = false;
22211        mSamplingInterval = 0;
22212    }
22213
22214    public boolean profileControl(String process, int userId, boolean start,
22215            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
22216
22217        try {
22218            synchronized (this) {
22219                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
22220                // its own permission.
22221                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
22222                        != PackageManager.PERMISSION_GRANTED) {
22223                    throw new SecurityException("Requires permission "
22224                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
22225                }
22226
22227                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
22228                    throw new IllegalArgumentException("null profile info or fd");
22229                }
22230
22231                ProcessRecord proc = null;
22232                if (process != null) {
22233                    proc = findProcessLocked(process, userId, "profileControl");
22234                }
22235
22236                if (start && (proc == null || proc.thread == null)) {
22237                    throw new IllegalArgumentException("Unknown process: " + process);
22238                }
22239
22240                if (start) {
22241                    stopProfilerLocked(null, 0);
22242                    setProfileApp(proc.info, proc.processName, profilerInfo);
22243                    mProfileProc = proc;
22244                    mProfileType = profileType;
22245                    ParcelFileDescriptor fd = profilerInfo.profileFd;
22246                    try {
22247                        fd = fd.dup();
22248                    } catch (IOException e) {
22249                        fd = null;
22250                    }
22251                    profilerInfo.profileFd = fd;
22252                    proc.thread.profilerControl(start, profilerInfo, profileType);
22253                    fd = null;
22254                    try {
22255                        mProfileFd.close();
22256                    } catch (IOException e) {
22257                    }
22258                    mProfileFd = null;
22259                } else {
22260                    stopProfilerLocked(proc, profileType);
22261                    if (profilerInfo != null && profilerInfo.profileFd != null) {
22262                        try {
22263                            profilerInfo.profileFd.close();
22264                        } catch (IOException e) {
22265                        }
22266                    }
22267                }
22268
22269                return true;
22270            }
22271        } catch (RemoteException e) {
22272            throw new IllegalStateException("Process disappeared");
22273        } finally {
22274            if (profilerInfo != null && profilerInfo.profileFd != null) {
22275                try {
22276                    profilerInfo.profileFd.close();
22277                } catch (IOException e) {
22278                }
22279            }
22280        }
22281    }
22282
22283    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
22284        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
22285                userId, true, ALLOW_FULL_ONLY, callName, null);
22286        ProcessRecord proc = null;
22287        try {
22288            int pid = Integer.parseInt(process);
22289            synchronized (mPidsSelfLocked) {
22290                proc = mPidsSelfLocked.get(pid);
22291            }
22292        } catch (NumberFormatException e) {
22293        }
22294
22295        if (proc == null) {
22296            ArrayMap<String, SparseArray<ProcessRecord>> all
22297                    = mProcessNames.getMap();
22298            SparseArray<ProcessRecord> procs = all.get(process);
22299            if (procs != null && procs.size() > 0) {
22300                proc = procs.valueAt(0);
22301                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
22302                    for (int i=1; i<procs.size(); i++) {
22303                        ProcessRecord thisProc = procs.valueAt(i);
22304                        if (thisProc.userId == userId) {
22305                            proc = thisProc;
22306                            break;
22307                        }
22308                    }
22309                }
22310            }
22311        }
22312
22313        return proc;
22314    }
22315
22316    public boolean dumpHeap(String process, int userId, boolean managed,
22317            String path, ParcelFileDescriptor fd) throws RemoteException {
22318
22319        try {
22320            synchronized (this) {
22321                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
22322                // its own permission (same as profileControl).
22323                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
22324                        != PackageManager.PERMISSION_GRANTED) {
22325                    throw new SecurityException("Requires permission "
22326                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
22327                }
22328
22329                if (fd == null) {
22330                    throw new IllegalArgumentException("null fd");
22331                }
22332
22333                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
22334                if (proc == null || proc.thread == null) {
22335                    throw new IllegalArgumentException("Unknown process: " + process);
22336                }
22337
22338                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
22339                if (!isDebuggable) {
22340                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
22341                        throw new SecurityException("Process not debuggable: " + proc);
22342                    }
22343                }
22344
22345                proc.thread.dumpHeap(managed, path, fd);
22346                fd = null;
22347                return true;
22348            }
22349        } catch (RemoteException e) {
22350            throw new IllegalStateException("Process disappeared");
22351        } finally {
22352            if (fd != null) {
22353                try {
22354                    fd.close();
22355                } catch (IOException e) {
22356                }
22357            }
22358        }
22359    }
22360
22361    @Override
22362    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
22363            String reportPackage) {
22364        if (processName != null) {
22365            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
22366                    "setDumpHeapDebugLimit()");
22367        } else {
22368            synchronized (mPidsSelfLocked) {
22369                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
22370                if (proc == null) {
22371                    throw new SecurityException("No process found for calling pid "
22372                            + Binder.getCallingPid());
22373                }
22374                if (!Build.IS_DEBUGGABLE
22375                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
22376                    throw new SecurityException("Not running a debuggable build");
22377                }
22378                processName = proc.processName;
22379                uid = proc.uid;
22380                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
22381                    throw new SecurityException("Package " + reportPackage + " is not running in "
22382                            + proc);
22383                }
22384            }
22385        }
22386        synchronized (this) {
22387            if (maxMemSize > 0) {
22388                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
22389            } else {
22390                if (uid != 0) {
22391                    mMemWatchProcesses.remove(processName, uid);
22392                } else {
22393                    mMemWatchProcesses.getMap().remove(processName);
22394                }
22395            }
22396        }
22397    }
22398
22399    @Override
22400    public void dumpHeapFinished(String path) {
22401        synchronized (this) {
22402            if (Binder.getCallingPid() != mMemWatchDumpPid) {
22403                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
22404                        + " does not match last pid " + mMemWatchDumpPid);
22405                return;
22406            }
22407            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
22408                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
22409                        + " does not match last path " + mMemWatchDumpFile);
22410                return;
22411            }
22412            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
22413            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
22414        }
22415    }
22416
22417    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
22418    public void monitor() {
22419        synchronized (this) { }
22420    }
22421
22422    void onCoreSettingsChange(Bundle settings) {
22423        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
22424            ProcessRecord processRecord = mLruProcesses.get(i);
22425            try {
22426                if (processRecord.thread != null) {
22427                    processRecord.thread.setCoreSettings(settings);
22428                }
22429            } catch (RemoteException re) {
22430                /* ignore */
22431            }
22432        }
22433    }
22434
22435    // Multi-user methods
22436
22437    /**
22438     * Start user, if its not already running, but don't bring it to foreground.
22439     */
22440    @Override
22441    public boolean startUserInBackground(final int userId) {
22442        return mUserController.startUser(userId, /* foreground */ false);
22443    }
22444
22445    @Override
22446    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
22447        return mUserController.unlockUser(userId, token, secret, listener);
22448    }
22449
22450    @Override
22451    public boolean switchUser(final int targetUserId) {
22452        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
22453        int currentUserId;
22454        UserInfo targetUserInfo;
22455        synchronized (this) {
22456            currentUserId = mUserController.getCurrentUserIdLocked();
22457            targetUserInfo = mUserController.getUserInfo(targetUserId);
22458            if (targetUserId == currentUserId) {
22459                Slog.i(TAG, "user #" + targetUserId + " is already the current user");
22460                return true;
22461            }
22462            if (targetUserInfo == null) {
22463                Slog.w(TAG, "No user info for user #" + targetUserId);
22464                return false;
22465            }
22466            if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
22467                Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
22468                        + " when device is in demo mode");
22469                return false;
22470            }
22471            if (!targetUserInfo.supportsSwitchTo()) {
22472                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
22473                return false;
22474            }
22475            if (targetUserInfo.isManagedProfile()) {
22476                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
22477                return false;
22478            }
22479            mUserController.setTargetUserIdLocked(targetUserId);
22480        }
22481        if (mUserController.mUserSwitchUiEnabled) {
22482            UserInfo currentUserInfo = mUserController.getUserInfo(currentUserId);
22483            Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
22484            mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
22485            mUiHandler.sendMessage(mHandler.obtainMessage(
22486                    START_USER_SWITCH_UI_MSG, userNames));
22487        } else {
22488            mHandler.removeMessages(START_USER_SWITCH_FG_MSG);
22489            mHandler.sendMessage(mHandler.obtainMessage(
22490                    START_USER_SWITCH_FG_MSG, targetUserId, 0));
22491        }
22492        return true;
22493    }
22494
22495    void scheduleStartProfilesLocked() {
22496        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
22497            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
22498                    DateUtils.SECOND_IN_MILLIS);
22499        }
22500    }
22501
22502    @Override
22503    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
22504        return mUserController.stopUser(userId, force, callback);
22505    }
22506
22507    @Override
22508    public UserInfo getCurrentUser() {
22509        return mUserController.getCurrentUser();
22510    }
22511
22512    String getStartedUserState(int userId) {
22513        synchronized (this) {
22514            final UserState userState = mUserController.getStartedUserStateLocked(userId);
22515            return UserState.stateToString(userState.state);
22516        }
22517    }
22518
22519    @Override
22520    public boolean isUserRunning(int userId, int flags) {
22521        if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
22522                && checkCallingPermission(INTERACT_ACROSS_USERS)
22523                    != PackageManager.PERMISSION_GRANTED) {
22524            String msg = "Permission Denial: isUserRunning() from pid="
22525                    + Binder.getCallingPid()
22526                    + ", uid=" + Binder.getCallingUid()
22527                    + " requires " + INTERACT_ACROSS_USERS;
22528            Slog.w(TAG, msg);
22529            throw new SecurityException(msg);
22530        }
22531        synchronized (this) {
22532            return mUserController.isUserRunningLocked(userId, flags);
22533        }
22534    }
22535
22536    @Override
22537    public int[] getRunningUserIds() {
22538        if (checkCallingPermission(INTERACT_ACROSS_USERS)
22539                != PackageManager.PERMISSION_GRANTED) {
22540            String msg = "Permission Denial: isUserRunning() from pid="
22541                    + Binder.getCallingPid()
22542                    + ", uid=" + Binder.getCallingUid()
22543                    + " requires " + INTERACT_ACROSS_USERS;
22544            Slog.w(TAG, msg);
22545            throw new SecurityException(msg);
22546        }
22547        synchronized (this) {
22548            return mUserController.getStartedUserArrayLocked();
22549        }
22550    }
22551
22552    @Override
22553    public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
22554        mUserController.registerUserSwitchObserver(observer, name);
22555    }
22556
22557    @Override
22558    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
22559        mUserController.unregisterUserSwitchObserver(observer);
22560    }
22561
22562    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
22563        if (info == null) return null;
22564        ApplicationInfo newInfo = new ApplicationInfo(info);
22565        newInfo.initForUser(userId);
22566        return newInfo;
22567    }
22568
22569    public boolean isUserStopped(int userId) {
22570        synchronized (this) {
22571            return mUserController.getStartedUserStateLocked(userId) == null;
22572        }
22573    }
22574
22575    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
22576        if (aInfo == null
22577                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
22578            return aInfo;
22579        }
22580
22581        ActivityInfo info = new ActivityInfo(aInfo);
22582        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
22583        return info;
22584    }
22585
22586    private boolean processSanityChecksLocked(ProcessRecord process) {
22587        if (process == null || process.thread == null) {
22588            return false;
22589        }
22590
22591        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
22592        if (!isDebuggable) {
22593            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
22594                return false;
22595            }
22596        }
22597
22598        return true;
22599    }
22600
22601    public boolean startBinderTracking() throws RemoteException {
22602        synchronized (this) {
22603            mBinderTransactionTrackingEnabled = true;
22604            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
22605            // permission (same as profileControl).
22606            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
22607                    != PackageManager.PERMISSION_GRANTED) {
22608                throw new SecurityException("Requires permission "
22609                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
22610            }
22611
22612            for (int i = 0; i < mLruProcesses.size(); i++) {
22613                ProcessRecord process = mLruProcesses.get(i);
22614                if (!processSanityChecksLocked(process)) {
22615                    continue;
22616                }
22617                try {
22618                    process.thread.startBinderTracking();
22619                } catch (RemoteException e) {
22620                    Log.v(TAG, "Process disappared");
22621                }
22622            }
22623            return true;
22624        }
22625    }
22626
22627    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
22628        try {
22629            synchronized (this) {
22630                mBinderTransactionTrackingEnabled = false;
22631                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
22632                // permission (same as profileControl).
22633                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
22634                        != PackageManager.PERMISSION_GRANTED) {
22635                    throw new SecurityException("Requires permission "
22636                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
22637                }
22638
22639                if (fd == null) {
22640                    throw new IllegalArgumentException("null fd");
22641                }
22642
22643                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
22644                pw.println("Binder transaction traces for all processes.\n");
22645                for (ProcessRecord process : mLruProcesses) {
22646                    if (!processSanityChecksLocked(process)) {
22647                        continue;
22648                    }
22649
22650                    pw.println("Traces for process: " + process.processName);
22651                    pw.flush();
22652                    try {
22653                        TransferPipe tp = new TransferPipe();
22654                        try {
22655                            process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
22656                            tp.go(fd.getFileDescriptor());
22657                        } finally {
22658                            tp.kill();
22659                        }
22660                    } catch (IOException e) {
22661                        pw.println("Failure while dumping IPC traces from " + process +
22662                                ".  Exception: " + e);
22663                        pw.flush();
22664                    } catch (RemoteException e) {
22665                        pw.println("Got a RemoteException while dumping IPC traces from " +
22666                                process + ".  Exception: " + e);
22667                        pw.flush();
22668                    }
22669                }
22670                fd = null;
22671                return true;
22672            }
22673        } finally {
22674            if (fd != null) {
22675                try {
22676                    fd.close();
22677                } catch (IOException e) {
22678                }
22679            }
22680        }
22681    }
22682
22683    private final class LocalService extends ActivityManagerInternal {
22684        @Override
22685        public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
22686                int targetUserId) {
22687            synchronized (ActivityManagerService.this) {
22688                ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
22689                        targetPkg, intent, null, targetUserId);
22690            }
22691        }
22692
22693        @Override
22694        public String checkContentProviderAccess(String authority, int userId) {
22695            return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
22696        }
22697
22698        @Override
22699        public void onWakefulnessChanged(int wakefulness) {
22700            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
22701        }
22702
22703        @Override
22704        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
22705                String processName, String abiOverride, int uid, Runnable crashHandler) {
22706            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
22707                    processName, abiOverride, uid, crashHandler);
22708        }
22709
22710        @Override
22711        public SleepToken acquireSleepToken(String tag) {
22712            Preconditions.checkNotNull(tag);
22713
22714            synchronized (ActivityManagerService.this) {
22715                SleepTokenImpl token = new SleepTokenImpl(tag);
22716                mSleepTokens.add(token);
22717                updateSleepIfNeededLocked();
22718                return token;
22719            }
22720        }
22721
22722        @Override
22723        public ComponentName getHomeActivityForUser(int userId) {
22724            synchronized (ActivityManagerService.this) {
22725                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
22726                return homeActivity == null ? null : homeActivity.realActivity;
22727            }
22728        }
22729
22730        @Override
22731        public void onUserRemoved(int userId) {
22732            synchronized (ActivityManagerService.this) {
22733                ActivityManagerService.this.onUserStoppedLocked(userId);
22734            }
22735        }
22736
22737        @Override
22738        public void onLocalVoiceInteractionStarted(IBinder activity,
22739                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
22740            synchronized (ActivityManagerService.this) {
22741                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
22742                        voiceSession, voiceInteractor);
22743            }
22744        }
22745
22746        @Override
22747        public void notifyStartingWindowDrawn() {
22748            synchronized (ActivityManagerService.this) {
22749                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
22750            }
22751        }
22752
22753        @Override
22754        public void notifyAppTransitionStarting(int reason) {
22755            synchronized (ActivityManagerService.this) {
22756                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
22757            }
22758        }
22759
22760        @Override
22761        public void notifyAppTransitionFinished() {
22762            synchronized (ActivityManagerService.this) {
22763                mStackSupervisor.notifyAppTransitionDone();
22764            }
22765        }
22766
22767        @Override
22768        public void notifyAppTransitionCancelled() {
22769            synchronized (ActivityManagerService.this) {
22770                mStackSupervisor.notifyAppTransitionDone();
22771            }
22772        }
22773
22774        @Override
22775        public List<IBinder> getTopVisibleActivities() {
22776            synchronized (ActivityManagerService.this) {
22777                return mStackSupervisor.getTopVisibleActivities();
22778            }
22779        }
22780
22781        @Override
22782        public void notifyDockedStackMinimizedChanged(boolean minimized) {
22783            synchronized (ActivityManagerService.this) {
22784                mStackSupervisor.setDockedStackMinimized(minimized);
22785            }
22786        }
22787
22788        @Override
22789        public void killForegroundAppsForUser(int userHandle) {
22790            synchronized (ActivityManagerService.this) {
22791                final ArrayList<ProcessRecord> procs = new ArrayList<>();
22792                final int NP = mProcessNames.getMap().size();
22793                for (int ip = 0; ip < NP; ip++) {
22794                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
22795                    final int NA = apps.size();
22796                    for (int ia = 0; ia < NA; ia++) {
22797                        final ProcessRecord app = apps.valueAt(ia);
22798                        if (app.persistent) {
22799                            // We don't kill persistent processes.
22800                            continue;
22801                        }
22802                        if (app.removed) {
22803                            procs.add(app);
22804                        } else if (app.userId == userHandle && app.foregroundActivities) {
22805                            app.removed = true;
22806                            procs.add(app);
22807                        }
22808                    }
22809                }
22810
22811                final int N = procs.size();
22812                for (int i = 0; i < N; i++) {
22813                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
22814                }
22815            }
22816        }
22817
22818        @Override
22819        public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
22820            if (!(target instanceof PendingIntentRecord)) {
22821                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
22822                return;
22823            }
22824            ((PendingIntentRecord) target).setWhitelistDuration(duration);
22825        }
22826
22827        @Override
22828        public void setDeviceIdleWhitelist(int[] appids) {
22829            synchronized (ActivityManagerService.this) {
22830                mDeviceIdleWhitelist = appids;
22831            }
22832        }
22833
22834        @Override
22835        public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) {
22836            synchronized (ActivityManagerService.this) {
22837                mDeviceIdleTempWhitelist = appids;
22838                setAppIdTempWhitelistStateLocked(changingAppId, adding);
22839            }
22840        }
22841
22842        @Override
22843        public void updatePersistentConfigurationForUser(@NonNull Configuration values,
22844                int userId) {
22845            Preconditions.checkNotNull(values, "Configuration must not be null");
22846            Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
22847            synchronized (ActivityManagerService.this) {
22848                updateConfigurationLocked(values, null, false, true, userId,
22849                        false /* deferResume */);
22850            }
22851        }
22852
22853        @Override
22854        public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
22855                Bundle bOptions) {
22856            Preconditions.checkNotNull(intents, "intents");
22857            final String[] resolvedTypes = new String[intents.length];
22858            for (int i = 0; i < intents.length; i++) {
22859                resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
22860            }
22861
22862            // UID of the package on user userId.
22863            // "= 0" is needed because otherwise catch(RemoteException) would make it look like
22864            // packageUid may not be initialized.
22865            int packageUid = 0;
22866            try {
22867                packageUid = AppGlobals.getPackageManager().getPackageUid(
22868                        packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
22869            } catch (RemoteException e) {
22870                // Shouldn't happen.
22871            }
22872
22873            synchronized (ActivityManagerService.this) {
22874                return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
22875                        /*resultTo*/ null, bOptions, userId);
22876            }
22877        }
22878
22879        @Override
22880        public int getUidProcessState(int uid) {
22881            return getUidState(uid);
22882        }
22883
22884        @Override
22885        public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
22886            synchronized (ActivityManagerService.this) {
22887
22888                // We might change the visibilities here, so prepare an empty app transition which
22889                // might be overridden later if we actually change visibilities.
22890                mWindowManager.prepareAppTransition(TRANSIT_NONE, false /* alwaysKeepCurrent */);
22891                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
22892                mWindowManager.executeAppTransition();
22893            }
22894            if (callback != null) {
22895                callback.run();
22896            }
22897        }
22898
22899        @Override
22900        public boolean isSystemReady() {
22901            // no need to synchronize(this) just to read & return the value
22902            return mSystemReady;
22903        }
22904
22905        @Override
22906        public void notifyKeyguardTrustedChanged() {
22907            synchronized (ActivityManagerService.this) {
22908                if (mKeyguardController.isKeyguardShowing()) {
22909                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
22910                }
22911            }
22912        }
22913
22914        /**
22915         * Sets if the given pid has an overlay UI or not.
22916         *
22917         * @param pid The pid we are setting overlay UI for.
22918         * @param hasOverlayUi True if the process has overlay UI.
22919         * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
22920         */
22921        @Override
22922        public void setHasOverlayUi(int pid, boolean hasOverlayUi) {
22923            synchronized (ActivityManagerService.this) {
22924                final ProcessRecord pr;
22925                synchronized (mPidsSelfLocked) {
22926                    pr = mPidsSelfLocked.get(pid);
22927                    if (pr == null) {
22928                        Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid);
22929                        return;
22930                    }
22931                }
22932                if (pr.hasOverlayUi == hasOverlayUi) {
22933                    return;
22934                }
22935                pr.hasOverlayUi = hasOverlayUi;
22936                //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
22937                updateOomAdjLocked(pr);
22938            }
22939        }
22940    }
22941
22942    private final class SleepTokenImpl extends SleepToken {
22943        private final String mTag;
22944        private final long mAcquireTime;
22945
22946        public SleepTokenImpl(String tag) {
22947            mTag = tag;
22948            mAcquireTime = SystemClock.uptimeMillis();
22949        }
22950
22951        @Override
22952        public void release() {
22953            synchronized (ActivityManagerService.this) {
22954                if (mSleepTokens.remove(this)) {
22955                    updateSleepIfNeededLocked();
22956                }
22957            }
22958        }
22959
22960        @Override
22961        public String toString() {
22962            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
22963        }
22964    }
22965
22966    /**
22967     * An implementation of IAppTask, that allows an app to manage its own tasks via
22968     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
22969     * only the process that calls getAppTasks() can call the AppTask methods.
22970     */
22971    class AppTaskImpl extends IAppTask.Stub {
22972        private int mTaskId;
22973        private int mCallingUid;
22974
22975        public AppTaskImpl(int taskId, int callingUid) {
22976            mTaskId = taskId;
22977            mCallingUid = callingUid;
22978        }
22979
22980        private void checkCaller() {
22981            if (mCallingUid != Binder.getCallingUid()) {
22982                throw new SecurityException("Caller " + mCallingUid
22983                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
22984            }
22985        }
22986
22987        @Override
22988        public void finishAndRemoveTask() {
22989            checkCaller();
22990
22991            synchronized (ActivityManagerService.this) {
22992                long origId = Binder.clearCallingIdentity();
22993                try {
22994                    // We remove the task from recents to preserve backwards
22995                    if (!mStackSupervisor.removeTaskByIdLocked(mTaskId, false,
22996                            REMOVE_FROM_RECENTS)) {
22997                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22998                    }
22999                } finally {
23000                    Binder.restoreCallingIdentity(origId);
23001                }
23002            }
23003        }
23004
23005        @Override
23006        public ActivityManager.RecentTaskInfo getTaskInfo() {
23007            checkCaller();
23008
23009            synchronized (ActivityManagerService.this) {
23010                long origId = Binder.clearCallingIdentity();
23011                try {
23012                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
23013                    if (tr == null) {
23014                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
23015                    }
23016                    return createRecentTaskInfoFromTaskRecord(tr);
23017                } finally {
23018                    Binder.restoreCallingIdentity(origId);
23019                }
23020            }
23021        }
23022
23023        @Override
23024        public void moveToFront() {
23025            checkCaller();
23026            // Will bring task to front if it already has a root activity.
23027            final long origId = Binder.clearCallingIdentity();
23028            try {
23029                synchronized (this) {
23030                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
23031                }
23032            } finally {
23033                Binder.restoreCallingIdentity(origId);
23034            }
23035        }
23036
23037        @Override
23038        public int startActivity(IBinder whoThread, String callingPackage,
23039                Intent intent, String resolvedType, Bundle bOptions) {
23040            checkCaller();
23041
23042            int callingUser = UserHandle.getCallingUserId();
23043            TaskRecord tr;
23044            IApplicationThread appThread;
23045            synchronized (ActivityManagerService.this) {
23046                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
23047                if (tr == null) {
23048                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
23049                }
23050                appThread = IApplicationThread.Stub.asInterface(whoThread);
23051                if (appThread == null) {
23052                    throw new IllegalArgumentException("Bad app thread " + appThread);
23053                }
23054            }
23055            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
23056                    resolvedType, null, null, null, null, 0, 0, null, null,
23057                    null, bOptions, false, callingUser, null, tr);
23058        }
23059
23060        @Override
23061        public void setExcludeFromRecents(boolean exclude) {
23062            checkCaller();
23063
23064            synchronized (ActivityManagerService.this) {
23065                long origId = Binder.clearCallingIdentity();
23066                try {
23067                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
23068                    if (tr == null) {
23069                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
23070                    }
23071                    Intent intent = tr.getBaseIntent();
23072                    if (exclude) {
23073                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
23074                    } else {
23075                        intent.setFlags(intent.getFlags()
23076                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
23077                    }
23078                } finally {
23079                    Binder.restoreCallingIdentity(origId);
23080                }
23081            }
23082        }
23083    }
23084
23085    /**
23086     * Kill processes for the user with id userId and that depend on the package named packageName
23087     */
23088    @Override
23089    public void killPackageDependents(String packageName, int userId) {
23090        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
23091        if (packageName == null) {
23092            throw new NullPointerException(
23093                    "Cannot kill the dependents of a package without its name.");
23094        }
23095
23096        long callingId = Binder.clearCallingIdentity();
23097        IPackageManager pm = AppGlobals.getPackageManager();
23098        int pkgUid = -1;
23099        try {
23100            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
23101        } catch (RemoteException e) {
23102        }
23103        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
23104            throw new IllegalArgumentException(
23105                    "Cannot kill dependents of non-existing package " + packageName);
23106        }
23107        try {
23108            synchronized(this) {
23109                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
23110                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
23111                        "dep: " + packageName);
23112            }
23113        } finally {
23114            Binder.restoreCallingIdentity(callingId);
23115        }
23116    }
23117
23118    @Override
23119    public boolean canBypassWorkChallenge(PendingIntent intent) throws RemoteException {
23120        final int userId = intent.getCreatorUserHandle().getIdentifier();
23121        if (!mUserController.isUserRunningLocked(userId, ActivityManager.FLAG_AND_LOCKED)) {
23122            return false;
23123        }
23124        IIntentSender target = intent.getTarget();
23125        if (!(target instanceof PendingIntentRecord)) {
23126            return false;
23127        }
23128        final PendingIntentRecord record = (PendingIntentRecord) target;
23129        final ResolveInfo rInfo = mStackSupervisor.resolveIntent(record.key.requestIntent,
23130                record.key.requestResolvedType, userId, PackageManager.MATCH_DIRECT_BOOT_AWARE);
23131        // For direct boot aware activities, they can be shown without triggering a work challenge
23132        // before the profile user is unlocked.
23133        return rInfo != null && rInfo.activityInfo != null;
23134    }
23135
23136    @Override
23137    public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback)
23138            throws RemoteException {
23139        final long callingId = Binder.clearCallingIdentity();
23140        try {
23141            mKeyguardController.dismissKeyguard(token, callback);
23142        } finally {
23143            Binder.restoreCallingIdentity(callingId);
23144        }
23145    }
23146
23147    @Override
23148    public int restartUserInBackground(final int userId) {
23149        return mUserController.restartUser(userId, /* foreground */ false);
23150    }
23151
23152    @Override
23153    public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) {
23154        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
23155                "scheduleApplicationInfoChanged()");
23156
23157        synchronized (this) {
23158            final long origId = Binder.clearCallingIdentity();
23159            try {
23160                updateApplicationInfoLocked(packageNames, userId);
23161            } finally {
23162                Binder.restoreCallingIdentity(origId);
23163            }
23164        }
23165    }
23166
23167    void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) {
23168        final boolean updateFrameworkRes = packagesToUpdate.contains("android");
23169        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
23170            final ProcessRecord app = mLruProcesses.get(i);
23171            if (app.thread == null) {
23172                continue;
23173            }
23174
23175            if (userId != UserHandle.USER_ALL && app.userId != userId) {
23176                continue;
23177            }
23178
23179            final int packageCount = app.pkgList.size();
23180            for (int j = 0; j < packageCount; j++) {
23181                final String packageName = app.pkgList.keyAt(j);
23182                if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
23183                    try {
23184                        final ApplicationInfo ai = mPackageManagerInt.getApplicationInfo(
23185                                packageName, app.userId);
23186                        if (ai != null) {
23187                            app.thread.scheduleApplicationInfoChanged(ai);
23188                        }
23189                    } catch (RemoteException e) {
23190                        Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
23191                                    packageName, app));
23192                    }
23193                }
23194            }
23195        }
23196    }
23197
23198    /**
23199     * Attach an agent to the specified process (proces name or PID)
23200     */
23201    public void attachAgent(String process, String path) {
23202        try {
23203            synchronized (this) {
23204                ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
23205                if (proc == null || proc.thread == null) {
23206                    throw new IllegalArgumentException("Unknown process: " + process);
23207                }
23208
23209                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23210                if (!isDebuggable) {
23211                    if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23212                        throw new SecurityException("Process not debuggable: " + proc);
23213                    }
23214                }
23215
23216                proc.thread.attachAgent(path);
23217            }
23218        } catch (RemoteException e) {
23219            throw new IllegalStateException("Process disappeared");
23220        }
23221    }
23222}
23223