ActivityManagerService.java revision bd54c2aab6acc50ac415dfc4a7462d12826e8223
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 android.app.ApplicationThreadConstants;
20import android.os.IDeviceIdentifiersPolicyService;
21import android.util.Size;
22import android.util.TypedValue;
23import android.view.DisplayInfo;
24import com.android.internal.telephony.TelephonyIntents;
25import com.google.android.collect.Lists;
26import com.google.android.collect.Maps;
27import com.android.internal.R;
28import com.android.internal.annotations.GuardedBy;
29import com.android.internal.app.AssistUtils;
30import com.android.internal.app.DumpHeapActivity;
31import com.android.internal.app.IAppOpsCallback;
32import com.android.internal.app.IAppOpsService;
33import com.android.internal.app.IVoiceInteractor;
34import com.android.internal.app.ProcessMap;
35import com.android.internal.app.SystemUserHomeActivity;
36import com.android.internal.app.procstats.ProcessStats;
37import com.android.internal.os.BackgroundThread;
38import com.android.internal.os.BatteryStatsImpl;
39import com.android.internal.os.IResultReceiver;
40import com.android.internal.os.ProcessCpuTracker;
41import com.android.internal.os.TransferPipe;
42import com.android.internal.os.Zygote;
43import com.android.internal.os.InstallerConnection.InstallerException;
44import com.android.internal.util.ArrayUtils;
45import com.android.internal.util.FastPrintWriter;
46import com.android.internal.util.FastXmlSerializer;
47import com.android.internal.util.MemInfoReader;
48import com.android.internal.util.Preconditions;
49import com.android.server.AppOpsService;
50import com.android.server.AttributeCache;
51import com.android.server.DeviceIdleController;
52import com.android.server.IntentResolver;
53import com.android.server.LocalServices;
54import com.android.server.LockGuard;
55import com.android.server.ServiceThread;
56import com.android.server.SystemService;
57import com.android.server.SystemServiceManager;
58import com.android.server.Watchdog;
59import com.android.server.am.ActivityStack.ActivityState;
60import com.android.server.firewall.IntentFirewall;
61import com.android.server.pm.Installer;
62import com.android.server.statusbar.StatusBarManagerInternal;
63import com.android.server.vr.VrManagerInternal;
64import com.android.server.wm.WindowManagerService;
65
66import org.xmlpull.v1.XmlPullParser;
67import org.xmlpull.v1.XmlPullParserException;
68import org.xmlpull.v1.XmlSerializer;
69
70import android.Manifest;
71import android.Manifest.permission;
72import android.annotation.NonNull;
73import android.annotation.UserIdInt;
74import android.app.Activity;
75import android.app.ActivityManager;
76import android.app.ActivityManager.RunningTaskInfo;
77import android.app.ActivityManager.StackId;
78import android.app.ActivityManager.StackInfo;
79import android.app.ActivityManager.TaskDescription;
80import android.app.ActivityManager.TaskThumbnailInfo;
81import android.app.ActivityManagerInternal;
82import android.app.ActivityManagerInternal.SleepToken;
83import android.app.ActivityManagerNative;
84import android.app.ActivityOptions;
85import android.app.ActivityThread;
86import android.app.AlertDialog;
87import android.app.AppGlobals;
88import android.app.AppOpsManager;
89import android.app.ApplicationErrorReport;
90import android.app.BroadcastOptions;
91import android.app.Dialog;
92import android.app.IActivityContainer;
93import android.app.IActivityContainerCallback;
94import android.app.IActivityController;
95import android.app.IAppTask;
96import android.app.IApplicationThread;
97import android.app.IInstrumentationWatcher;
98import android.app.INotificationManager;
99import android.app.IProcessObserver;
100import android.app.IServiceConnection;
101import android.app.IStopUserCallback;
102import android.app.ITaskStackListener;
103import android.app.IUiAutomationConnection;
104import android.app.IUidObserver;
105import android.app.IUserSwitchObserver;
106import android.app.Instrumentation;
107import android.app.Notification;
108import android.app.NotificationManager;
109import android.app.PendingIntent;
110import android.app.ProfilerInfo;
111import android.app.admin.DevicePolicyManager;
112import android.app.assist.AssistContent;
113import android.app.assist.AssistStructure;
114import android.app.backup.IBackupManager;
115import android.app.usage.UsageEvents;
116import android.app.usage.UsageStatsManagerInternal;
117import android.appwidget.AppWidgetManager;
118import android.content.ActivityNotFoundException;
119import android.content.BroadcastReceiver;
120import android.content.ClipData;
121import android.content.ComponentCallbacks2;
122import android.content.ComponentName;
123import android.content.ContentProvider;
124import android.content.ContentResolver;
125import android.content.Context;
126import android.content.DialogInterface;
127import android.content.IContentProvider;
128import android.content.IIntentReceiver;
129import android.content.IIntentSender;
130import android.content.Intent;
131import android.content.IntentFilter;
132import android.content.IntentSender;
133import android.content.pm.ActivityInfo;
134import android.content.pm.ApplicationInfo;
135import android.content.pm.ConfigurationInfo;
136import android.content.pm.IPackageDataObserver;
137import android.content.pm.IPackageManager;
138import android.content.pm.InstrumentationInfo;
139import android.content.pm.PackageInfo;
140import android.content.pm.PackageManager;
141import android.content.pm.PackageManager.NameNotFoundException;
142import android.content.pm.PackageManagerInternal;
143import android.content.pm.ParceledListSlice;
144import android.content.pm.PathPermission;
145import android.content.pm.PermissionInfo;
146import android.content.pm.ProviderInfo;
147import android.content.pm.ResolveInfo;
148import android.content.pm.ServiceInfo;
149import android.content.pm.UserInfo;
150import android.content.res.CompatibilityInfo;
151import android.content.res.Configuration;
152import android.content.res.Resources;
153import android.database.ContentObserver;
154import android.graphics.Bitmap;
155import android.graphics.Point;
156import android.graphics.Rect;
157import android.location.LocationManager;
158import android.net.Proxy;
159import android.net.ProxyInfo;
160import android.net.Uri;
161import android.os.BatteryStats;
162import android.os.Binder;
163import android.os.Build;
164import android.os.Bundle;
165import android.os.Debug;
166import android.os.DropBoxManager;
167import android.os.Environment;
168import android.os.FactoryTest;
169import android.os.FileObserver;
170import android.os.FileUtils;
171import android.os.Handler;
172import android.os.IBinder;
173import android.os.IPermissionController;
174import android.os.IProcessInfoService;
175import android.os.IProgressListener;
176import android.os.LocaleList;
177import android.os.Looper;
178import android.os.Message;
179import android.os.Parcel;
180import android.os.ParcelFileDescriptor;
181import android.os.PersistableBundle;
182import android.os.PowerManager;
183import android.os.PowerManagerInternal;
184import android.os.Process;
185import android.os.RemoteCallbackList;
186import android.os.RemoteException;
187import android.os.ResultReceiver;
188import android.os.ServiceManager;
189import android.os.ShellCallback;
190import android.os.StrictMode;
191import android.os.SystemClock;
192import android.os.SystemProperties;
193import android.os.Trace;
194import android.os.TransactionTooLargeException;
195import android.os.UpdateLock;
196import android.os.UserHandle;
197import android.os.UserManager;
198import android.os.WorkSource;
199import android.os.storage.IMountService;
200import android.os.storage.MountServiceInternal;
201import android.os.storage.StorageManager;
202import android.provider.Settings;
203import android.service.voice.IVoiceInteractionSession;
204import android.service.voice.VoiceInteractionManagerInternal;
205import android.service.voice.VoiceInteractionSession;
206import android.telecom.TelecomManager;
207import android.text.format.DateUtils;
208import android.text.format.Time;
209import android.text.style.SuggestionSpan;
210import android.util.ArrayMap;
211import android.util.ArraySet;
212import android.util.AtomicFile;
213import android.util.DebugUtils;
214import android.util.DisplayMetrics;
215import android.util.EventLog;
216import android.util.Log;
217import android.util.Pair;
218import android.util.PrintWriterPrinter;
219import android.util.Slog;
220import android.util.SparseArray;
221import android.util.TimeUtils;
222import android.util.Xml;
223import android.view.Gravity;
224import android.view.LayoutInflater;
225import android.view.View;
226import android.view.WindowManager;
227
228import java.io.File;
229import java.io.FileDescriptor;
230import java.io.FileInputStream;
231import java.io.FileNotFoundException;
232import java.io.FileOutputStream;
233import java.io.IOException;
234import java.io.InputStreamReader;
235import java.io.PrintWriter;
236import java.io.StringWriter;
237import java.lang.ref.WeakReference;
238import java.nio.charset.StandardCharsets;
239import java.util.ArrayList;
240import java.util.Arrays;
241import java.util.Collections;
242import java.util.Comparator;
243import java.util.HashMap;
244import java.util.HashSet;
245import java.util.Iterator;
246import java.util.List;
247import java.util.Locale;
248import java.util.Map;
249import java.util.Objects;
250import java.util.Set;
251import java.util.concurrent.atomic.AtomicBoolean;
252import java.util.concurrent.atomic.AtomicLong;
253
254import dalvik.system.VMRuntime;
255
256import libcore.io.IoUtils;
257import libcore.util.EmptyArray;
258
259import static android.Manifest.permission.CHANGE_CONFIGURATION;
260import static android.Manifest.permission.INTERACT_ACROSS_USERS;
261import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
262import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
263import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
264import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
265import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
266import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
267import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
268import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
269import static android.app.ActivityManager.StackId.HOME_STACK_ID;
270import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
271import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
272import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
273import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
274import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
275import static android.content.pm.PackageManager.GET_PROVIDERS;
276import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
277import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
278import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
279import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
280import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
281import static android.content.pm.PackageManager.PERMISSION_GRANTED;
282import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
283import static android.os.Build.VERSION_CODES.N;
284import static android.os.Process.PROC_CHAR;
285import static android.os.Process.PROC_OUT_LONG;
286import static android.os.Process.PROC_PARENS;
287import static android.os.Process.PROC_SPACE_TERM;
288import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
289import static android.provider.Settings.Global.DEBUG_APP;
290import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
291import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
292import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
293import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
294import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
295import static android.provider.Settings.System.FONT_SCALE;
296import static android.util.TypedValue.COMPLEX_UNIT_DIP;
297import static android.view.Display.DEFAULT_DISPLAY;
298
299import static com.android.internal.util.XmlUtils.readBooleanAttribute;
300import static com.android.internal.util.XmlUtils.readIntAttribute;
301import static com.android.internal.util.XmlUtils.readLongAttribute;
302import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
303import static com.android.internal.util.XmlUtils.writeIntAttribute;
304import static com.android.internal.util.XmlUtils.writeLongAttribute;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
315import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
316import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
317import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
318import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
319import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
320import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
321import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
322import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
323import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
324import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
325import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
326import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
327import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
328import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
329import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
330import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
331import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
332import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
333import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
334import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
335import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
336import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
337import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
338import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
339import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
340import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
341import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
342import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
343import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
344import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
345import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
346import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
347import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
348import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
349import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
350import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
351import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
352import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
353import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
354import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
355import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
356import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
357import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
358import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
359import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
360import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
361import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
362import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
363import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
364import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
365import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
366import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
367import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
368import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
369import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
370import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
371import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
372import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
373import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
374import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
375import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
376import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
377import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
378import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
379import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
380import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
381import static org.xmlpull.v1.XmlPullParser.START_TAG;
382
383public final class ActivityManagerService extends ActivityManagerNative
384        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
385
386    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
387    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
388    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
389    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
390    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
391    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
392    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
393    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
394    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
395    private static final String TAG_LRU = TAG + POSTFIX_LRU;
396    private static final String TAG_MU = TAG + POSTFIX_MU;
397    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
398    private static final String TAG_POWER = TAG + POSTFIX_POWER;
399    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
400    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
401    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
402    private static final String TAG_PSS = TAG + POSTFIX_PSS;
403    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
404    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
405    private static final String TAG_STACK = TAG + POSTFIX_STACK;
406    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
407    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
408    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
409    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
410    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
411
412    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
413    // here so that while the job scheduler can depend on AMS, the other way around
414    // need not be the case.
415    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
416
417    /** Control over CPU and battery monitoring */
418    // write battery stats every 30 minutes.
419    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
420    static final boolean MONITOR_CPU_USAGE = true;
421    // don't sample cpu less than every 5 seconds.
422    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
423    // wait possibly forever for next cpu sample.
424    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
425    static final boolean MONITOR_THREAD_CPU_USAGE = false;
426
427    // The flags that are set for all calls we make to the package manager.
428    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
429
430    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
431
432    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
433
434    // Amount of time after a call to stopAppSwitches() during which we will
435    // prevent further untrusted switches from happening.
436    static final long APP_SWITCH_DELAY_TIME = 5*1000;
437
438    // How long we wait for a launched process to attach to the activity manager
439    // before we decide it's never going to come up for real.
440    static final int PROC_START_TIMEOUT = 10*1000;
441    // How long we wait for an attached process to publish its content providers
442    // before we decide it must be hung.
443    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
444
445    // How long we will retain processes hosting content providers in the "last activity"
446    // state before allowing them to drop down to the regular cached LRU list.  This is
447    // to avoid thrashing of provider processes under low memory situations.
448    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
449
450    // How long we wait for a launched process to attach to the activity manager
451    // before we decide it's never going to come up for real, when the process was
452    // started with a wrapper for instrumentation (such as Valgrind) because it
453    // could take much longer than usual.
454    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
455
456    // How long to wait after going idle before forcing apps to GC.
457    static final int GC_TIMEOUT = 5*1000;
458
459    // The minimum amount of time between successive GC requests for a process.
460    static final int GC_MIN_INTERVAL = 60*1000;
461
462    // The minimum amount of time between successive PSS requests for a process.
463    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
464
465    // The minimum amount of time between successive PSS requests for a process
466    // when the request is due to the memory state being lowered.
467    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
468
469    // The rate at which we check for apps using excessive power -- 15 mins.
470    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
471
472    // The minimum sample duration we will allow before deciding we have
473    // enough data on wake locks to start killing things.
474    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
475
476    // The minimum sample duration we will allow before deciding we have
477    // enough data on CPU usage to start killing things.
478    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
479
480    // How long we allow a receiver to run before giving up on it.
481    static final int BROADCAST_FG_TIMEOUT = 10*1000;
482    static final int BROADCAST_BG_TIMEOUT = 60*1000;
483
484    // How long we wait until we timeout on key dispatching.
485    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
486
487    // How long we wait until we timeout on key dispatching during instrumentation.
488    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
489
490    // This is the amount of time an app needs to be running a foreground service before
491    // we will consider it to be doing interaction for usage stats.
492    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
493
494    // Maximum amount of time we will allow to elapse before re-reporting usage stats
495    // interaction with foreground processes.
496    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
497
498    // This is the amount of time we allow an app to settle after it goes into the background,
499    // before we start restricting what it can do.
500    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
501
502    // How long to wait in getAssistContextExtras for the activity and foreground services
503    // to respond with the result.
504    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
505
506    // How long top wait when going through the modern assist (which doesn't need to block
507    // on getting this result before starting to launch its UI).
508    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
509
510    // Maximum number of persisted Uri grants a package is allowed
511    static final int MAX_PERSISTED_URI_GRANTS = 128;
512
513    static final int MY_PID = Process.myPid();
514
515    static final String[] EMPTY_STRING_ARRAY = new String[0];
516
517    // How many bytes to write into the dropbox log before truncating
518    static final int DROPBOX_MAX_SIZE = 192 * 1024;
519    // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
520    // as one line, but close enough for now.
521    static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
522
523    // Access modes for handleIncomingUser.
524    static final int ALLOW_NON_FULL = 0;
525    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
526    static final int ALLOW_FULL_ONLY = 2;
527
528    // Necessary ApplicationInfo flags to mark an app as persistent
529    private static final int PERSISTENT_MASK =
530            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
531
532    // Intent sent when remote bugreport collection has been completed
533    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
534            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
535
536    // Used to indicate that a task is removed it should also be removed from recents.
537    private static final boolean REMOVE_FROM_RECENTS = true;
538    // Used to indicate that an app transition should be animated.
539    static final boolean ANIMATE = true;
540
541    // Determines whether to take full screen screenshots
542    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
543    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
544
545    /** All system services */
546    SystemServiceManager mSystemServiceManager;
547
548    private Installer mInstaller;
549
550    /** Run all ActivityStacks through this */
551    final ActivityStackSupervisor mStackSupervisor;
552
553    final ActivityStarter mActivityStarter;
554
555    final TaskChangeNotificationController mTaskChangeNotificationController;
556
557    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
558
559    public IntentFirewall mIntentFirewall;
560
561    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
562    // default action automatically.  Important for devices without direct input
563    // devices.
564    private boolean mShowDialogs = true;
565    private boolean mInVrMode = false;
566
567    // Whether we should use SCHED_FIFO for UI and RenderThreads.
568    private boolean mUseFifoUiScheduling = false;
569
570    BroadcastQueue mFgBroadcastQueue;
571    BroadcastQueue mBgBroadcastQueue;
572    // Convenient for easy iteration over the queues. Foreground is first
573    // so that dispatch of foreground broadcasts gets precedence.
574    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
575
576    BroadcastStats mLastBroadcastStats;
577    BroadcastStats mCurBroadcastStats;
578
579    BroadcastQueue broadcastQueueForIntent(Intent intent) {
580        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
581        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
582                "Broadcast intent " + intent + " on "
583                + (isFg ? "foreground" : "background") + " queue");
584        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
585    }
586
587    /**
588     * The last resumed activity. This is identical to the current resumed activity most
589     * of the time but could be different when we're pausing one activity before we resume
590     * another activity.
591     */
592    private ActivityRecord mLastResumedActivity;
593
594    /**
595     * If non-null, we are tracking the time the user spends in the currently focused app.
596     */
597    private AppTimeTracker mCurAppTimeTracker;
598
599    /**
600     * List of intents that were used to start the most recent tasks.
601     */
602    final RecentTasks mRecentTasks;
603
604    /**
605     * For addAppTask: cached of the last activity component that was added.
606     */
607    ComponentName mLastAddedTaskComponent;
608
609    /**
610     * For addAppTask: cached of the last activity uid that was added.
611     */
612    int mLastAddedTaskUid;
613
614    /**
615     * For addAppTask: cached of the last ActivityInfo that was added.
616     */
617    ActivityInfo mLastAddedTaskActivity;
618
619    /**
620     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
621     */
622    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
623
624    /**
625     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
626     */
627    String mDeviceOwnerName;
628
629    final UserController mUserController;
630
631    final AppErrors mAppErrors;
632
633    public boolean canShowErrorDialogs() {
634        return mShowDialogs && !mSleeping && !mShuttingDown
635                && mLockScreenShown != LOCK_SCREEN_SHOWN;
636    }
637
638    private static final class PriorityState {
639        // Acts as counter for number of synchronized region that needs to acquire 'this' as a lock
640        // the current thread is currently in. When it drops down to zero, we will no longer boost
641        // the thread's priority.
642        private int regionCounter = 0;
643
644        // The thread's previous priority before boosting.
645        private int prevPriority = Integer.MIN_VALUE;
646    }
647
648    static ThreadLocal<PriorityState> sThreadPriorityState = new ThreadLocal<PriorityState>() {
649        @Override protected PriorityState initialValue() {
650            return new PriorityState();
651        }
652    };
653
654    static void boostPriorityForLockedSection() {
655        int tid = Process.myTid();
656        int prevPriority = Process.getThreadPriority(tid);
657        PriorityState state = sThreadPriorityState.get();
658        if (state.regionCounter == 0 && prevPriority > -2) {
659            state.prevPriority = prevPriority;
660            Process.setThreadPriority(tid, -2);
661        }
662        state.regionCounter++;
663    }
664
665    static void resetPriorityAfterLockedSection() {
666        PriorityState state = sThreadPriorityState.get();
667        state.regionCounter--;
668        if (state.regionCounter == 0 && state.prevPriority > -2) {
669            Process.setThreadPriority(Process.myTid(), state.prevPriority);
670        }
671    }
672
673    public class PendingAssistExtras extends Binder implements Runnable {
674        public final ActivityRecord activity;
675        public final Bundle extras;
676        public final Intent intent;
677        public final String hint;
678        public final IResultReceiver receiver;
679        public final int userHandle;
680        public boolean haveResult = false;
681        public Bundle result = null;
682        public AssistStructure structure = null;
683        public AssistContent content = null;
684        public Bundle receiverExtras;
685
686        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
687                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
688            activity = _activity;
689            extras = _extras;
690            intent = _intent;
691            hint = _hint;
692            receiver = _receiver;
693            receiverExtras = _receiverExtras;
694            userHandle = _userHandle;
695        }
696        @Override
697        public void run() {
698            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
699            synchronized (this) {
700                haveResult = true;
701                notifyAll();
702            }
703            pendingAssistExtrasTimedOut(this);
704        }
705    }
706
707    final ArrayList<PendingAssistExtras> mPendingAssistExtras
708            = new ArrayList<PendingAssistExtras>();
709
710    /**
711     * Process management.
712     */
713    final ProcessList mProcessList = new ProcessList();
714
715    /**
716     * All of the applications we currently have running organized by name.
717     * The keys are strings of the application package name (as
718     * returned by the package manager), and the keys are ApplicationRecord
719     * objects.
720     */
721    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
722
723    /**
724     * Tracking long-term execution of processes to look for abuse and other
725     * bad app behavior.
726     */
727    final ProcessStatsService mProcessStats;
728
729    /**
730     * The currently running isolated processes.
731     */
732    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
733
734    /**
735     * Counter for assigning isolated process uids, to avoid frequently reusing the
736     * same ones.
737     */
738    int mNextIsolatedProcessUid = 0;
739
740    /**
741     * The currently running heavy-weight process, if any.
742     */
743    ProcessRecord mHeavyWeightProcess = null;
744
745    /**
746     * All of the processes we currently have running organized by pid.
747     * The keys are the pid running the application.
748     *
749     * <p>NOTE: This object is protected by its own lock, NOT the global
750     * activity manager lock!
751     */
752    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
753
754    /**
755     * All of the processes that have been forced to be foreground.  The key
756     * is the pid of the caller who requested it (we hold a death
757     * link on it).
758     */
759    abstract class ForegroundToken implements IBinder.DeathRecipient {
760        int pid;
761        IBinder token;
762    }
763    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
764
765    /**
766     * List of records for processes that someone had tried to start before the
767     * system was ready.  We don't start them at that point, but ensure they
768     * are started by the time booting is complete.
769     */
770    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
771
772    /**
773     * List of persistent applications that are in the process
774     * of being started.
775     */
776    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
777
778    /**
779     * Processes that are being forcibly torn down.
780     */
781    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
782
783    /**
784     * List of running applications, sorted by recent usage.
785     * The first entry in the list is the least recently used.
786     */
787    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
788
789    /**
790     * Where in mLruProcesses that the processes hosting activities start.
791     */
792    int mLruProcessActivityStart = 0;
793
794    /**
795     * Where in mLruProcesses that the processes hosting services start.
796     * This is after (lower index) than mLruProcessesActivityStart.
797     */
798    int mLruProcessServiceStart = 0;
799
800    /**
801     * List of processes that should gc as soon as things are idle.
802     */
803    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
804
805    /**
806     * Processes we want to collect PSS data from.
807     */
808    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
809
810    private boolean mBinderTransactionTrackingEnabled = false;
811
812    /**
813     * Last time we requested PSS data of all processes.
814     */
815    long mLastFullPssTime = SystemClock.uptimeMillis();
816
817    /**
818     * If set, the next time we collect PSS data we should do a full collection
819     * with data from native processes and the kernel.
820     */
821    boolean mFullPssPending = false;
822
823    /**
824     * This is the process holding what we currently consider to be
825     * the "home" activity.
826     */
827    ProcessRecord mHomeProcess;
828
829    /**
830     * This is the process holding the activity the user last visited that
831     * is in a different process from the one they are currently in.
832     */
833    ProcessRecord mPreviousProcess;
834
835    /**
836     * The time at which the previous process was last visible.
837     */
838    long mPreviousProcessVisibleTime;
839
840    /**
841     * Track all uids that have actively running processes.
842     */
843    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
844
845    /**
846     * This is for verifying the UID report flow.
847     */
848    static final boolean VALIDATE_UID_STATES = true;
849    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
850
851    /**
852     * Packages that the user has asked to have run in screen size
853     * compatibility mode instead of filling the screen.
854     */
855    final CompatModePackages mCompatModePackages;
856
857    /**
858     * Set of IntentSenderRecord objects that are currently active.
859     */
860    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
861            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
862
863    /**
864     * Fingerprints (hashCode()) of stack traces that we've
865     * already logged DropBox entries for.  Guarded by itself.  If
866     * something (rogue user app) forces this over
867     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
868     */
869    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
870    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
871
872    /**
873     * Strict Mode background batched logging state.
874     *
875     * The string buffer is guarded by itself, and its lock is also
876     * used to determine if another batched write is already
877     * in-flight.
878     */
879    private final StringBuilder mStrictModeBuffer = new StringBuilder();
880
881    /**
882     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
883     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
884     */
885    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
886
887    /**
888     * Resolver for broadcast intents to registered receivers.
889     * Holds BroadcastFilter (subclass of IntentFilter).
890     */
891    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
892            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
893        @Override
894        protected boolean allowFilterResult(
895                BroadcastFilter filter, List<BroadcastFilter> dest) {
896            IBinder target = filter.receiverList.receiver.asBinder();
897            for (int i = dest.size() - 1; i >= 0; i--) {
898                if (dest.get(i).receiverList.receiver.asBinder() == target) {
899                    return false;
900                }
901            }
902            return true;
903        }
904
905        @Override
906        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
907            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
908                    || userId == filter.owningUserId) {
909                return super.newResult(filter, match, userId);
910            }
911            return null;
912        }
913
914        @Override
915        protected BroadcastFilter[] newArray(int size) {
916            return new BroadcastFilter[size];
917        }
918
919        @Override
920        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
921            return packageName.equals(filter.packageName);
922        }
923    };
924
925    /**
926     * State of all active sticky broadcasts per user.  Keys are the action of the
927     * sticky Intent, values are an ArrayList of all broadcasted intents with
928     * that action (which should usually be one).  The SparseArray is keyed
929     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
930     * for stickies that are sent to all users.
931     */
932    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
933            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
934
935    final ActiveServices mServices;
936
937    final static class Association {
938        final int mSourceUid;
939        final String mSourceProcess;
940        final int mTargetUid;
941        final ComponentName mTargetComponent;
942        final String mTargetProcess;
943
944        int mCount;
945        long mTime;
946
947        int mNesting;
948        long mStartTime;
949
950        // states of the source process when the bind occurred.
951        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
952        long mLastStateUptime;
953        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
954                - ActivityManager.MIN_PROCESS_STATE+1];
955
956        Association(int sourceUid, String sourceProcess, int targetUid,
957                ComponentName targetComponent, String targetProcess) {
958            mSourceUid = sourceUid;
959            mSourceProcess = sourceProcess;
960            mTargetUid = targetUid;
961            mTargetComponent = targetComponent;
962            mTargetProcess = targetProcess;
963        }
964    }
965
966    /**
967     * When service association tracking is enabled, this is all of the associations we
968     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
969     * -> association data.
970     */
971    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
972            mAssociations = new SparseArray<>();
973    boolean mTrackingAssociations;
974
975    /**
976     * Backup/restore process management
977     */
978    String mBackupAppName = null;
979    BackupRecord mBackupTarget = null;
980
981    final ProviderMap mProviderMap;
982
983    /**
984     * List of content providers who have clients waiting for them.  The
985     * application is currently being launched and the provider will be
986     * removed from this list once it is published.
987     */
988    final ArrayList<ContentProviderRecord> mLaunchingProviders
989            = new ArrayList<ContentProviderRecord>();
990
991    /**
992     * File storing persisted {@link #mGrantedUriPermissions}.
993     */
994    private final AtomicFile mGrantFile;
995
996    /** XML constants used in {@link #mGrantFile} */
997    private static final String TAG_URI_GRANTS = "uri-grants";
998    private static final String TAG_URI_GRANT = "uri-grant";
999    private static final String ATTR_USER_HANDLE = "userHandle";
1000    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1001    private static final String ATTR_TARGET_USER_ID = "targetUserId";
1002    private static final String ATTR_SOURCE_PKG = "sourcePkg";
1003    private static final String ATTR_TARGET_PKG = "targetPkg";
1004    private static final String ATTR_URI = "uri";
1005    private static final String ATTR_MODE_FLAGS = "modeFlags";
1006    private static final String ATTR_CREATED_TIME = "createdTime";
1007    private static final String ATTR_PREFIX = "prefix";
1008
1009    /**
1010     * Global set of specific {@link Uri} permissions that have been granted.
1011     * This optimized lookup structure maps from {@link UriPermission#targetUid}
1012     * to {@link UriPermission#uri} to {@link UriPermission}.
1013     */
1014    @GuardedBy("this")
1015    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1016            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1017
1018    public static class GrantUri {
1019        public final int sourceUserId;
1020        public final Uri uri;
1021        public boolean prefix;
1022
1023        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1024            this.sourceUserId = sourceUserId;
1025            this.uri = uri;
1026            this.prefix = prefix;
1027        }
1028
1029        @Override
1030        public int hashCode() {
1031            int hashCode = 1;
1032            hashCode = 31 * hashCode + sourceUserId;
1033            hashCode = 31 * hashCode + uri.hashCode();
1034            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1035            return hashCode;
1036        }
1037
1038        @Override
1039        public boolean equals(Object o) {
1040            if (o instanceof GrantUri) {
1041                GrantUri other = (GrantUri) o;
1042                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1043                        && prefix == other.prefix;
1044            }
1045            return false;
1046        }
1047
1048        @Override
1049        public String toString() {
1050            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1051            if (prefix) result += " [prefix]";
1052            return result;
1053        }
1054
1055        public String toSafeString() {
1056            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1057            if (prefix) result += " [prefix]";
1058            return result;
1059        }
1060
1061        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1062            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1063                    ContentProvider.getUriWithoutUserId(uri), false);
1064        }
1065    }
1066
1067    CoreSettingsObserver mCoreSettingsObserver;
1068
1069    FontScaleSettingObserver mFontScaleSettingObserver;
1070
1071    private final class FontScaleSettingObserver extends ContentObserver {
1072        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1073
1074        public FontScaleSettingObserver() {
1075            super(mHandler);
1076            ContentResolver resolver = mContext.getContentResolver();
1077            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1078        }
1079
1080        @Override
1081        public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1082            if (mFontScaleUri.equals(uri)) {
1083                updateFontScaleIfNeeded(userId);
1084            }
1085        }
1086    }
1087
1088    /**
1089     * Thread-local storage used to carry caller permissions over through
1090     * indirect content-provider access.
1091     */
1092    private class Identity {
1093        public final IBinder token;
1094        public final int pid;
1095        public final int uid;
1096
1097        Identity(IBinder _token, int _pid, int _uid) {
1098            token = _token;
1099            pid = _pid;
1100            uid = _uid;
1101        }
1102    }
1103
1104    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1105
1106    /**
1107     * All information we have collected about the runtime performance of
1108     * any user id that can impact battery performance.
1109     */
1110    final BatteryStatsService mBatteryStatsService;
1111
1112    /**
1113     * Information about component usage
1114     */
1115    UsageStatsManagerInternal mUsageStatsService;
1116
1117    /**
1118     * Access to DeviceIdleController service.
1119     */
1120    DeviceIdleController.LocalService mLocalDeviceIdleController;
1121
1122    /**
1123     * Information about and control over application operations
1124     */
1125    final AppOpsService mAppOpsService;
1126
1127    /** Current sequencing integer of the configuration, for skipping old configurations. */
1128    private int mConfigurationSeq;
1129
1130    /**
1131     * Temp object used when global and/or display override configuration is updated. It is also
1132     * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
1133     * anyone...
1134     */
1135    private Configuration mTempConfig = new Configuration();
1136
1137    private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
1138            new UpdateConfigurationResult();
1139    private static final class UpdateConfigurationResult {
1140        // Configuration changes that were updated.
1141        int changes;
1142        // If the activity was relaunched to match the new configuration.
1143        boolean activityRelaunched;
1144
1145        void reset() {
1146            changes = 0;
1147            activityRelaunched = false;
1148        }
1149    }
1150
1151    boolean mSuppressResizeConfigChanges;
1152
1153    /**
1154     * Hardware-reported OpenGLES version.
1155     */
1156    final int GL_ES_VERSION;
1157
1158    /**
1159     * List of initialization arguments to pass to all processes when binding applications to them.
1160     * For example, references to the commonly used services.
1161     */
1162    HashMap<String, IBinder> mAppBindArgs;
1163    HashMap<String, IBinder> mIsolatedAppBindArgs;
1164
1165    /**
1166     * Temporary to avoid allocations.  Protected by main lock.
1167     */
1168    final StringBuilder mStringBuilder = new StringBuilder(256);
1169
1170    /**
1171     * Used to control how we initialize the service.
1172     */
1173    ComponentName mTopComponent;
1174    String mTopAction = Intent.ACTION_MAIN;
1175    String mTopData;
1176
1177    volatile boolean mProcessesReady = false;
1178    volatile boolean mSystemReady = false;
1179    volatile boolean mOnBattery = false;
1180    volatile int mFactoryTest;
1181
1182    @GuardedBy("this") boolean mBooting = false;
1183    @GuardedBy("this") boolean mCallFinishBooting = false;
1184    @GuardedBy("this") boolean mBootAnimationComplete = false;
1185    @GuardedBy("this") boolean mLaunchWarningShown = false;
1186    @GuardedBy("this") boolean mCheckedForSetup = false;
1187
1188    Context mContext;
1189
1190    /**
1191     * The time at which we will allow normal application switches again,
1192     * after a call to {@link #stopAppSwitches()}.
1193     */
1194    long mAppSwitchesAllowedTime;
1195
1196    /**
1197     * This is set to true after the first switch after mAppSwitchesAllowedTime
1198     * is set; any switches after that will clear the time.
1199     */
1200    boolean mDidAppSwitch;
1201
1202    /**
1203     * Last time (in realtime) at which we checked for power usage.
1204     */
1205    long mLastPowerCheckRealtime;
1206
1207    /**
1208     * Last time (in uptime) at which we checked for power usage.
1209     */
1210    long mLastPowerCheckUptime;
1211
1212    /**
1213     * Set while we are wanting to sleep, to prevent any
1214     * activities from being started/resumed.
1215     */
1216    private boolean mSleeping = false;
1217
1218    /**
1219     * The process state used for processes that are running the top activities.
1220     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1221     */
1222    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1223
1224    /**
1225     * Set while we are running a voice interaction.  This overrides
1226     * sleeping while it is active.
1227     */
1228    private IVoiceInteractionSession mRunningVoice;
1229
1230    /**
1231     * For some direct access we need to power manager.
1232     */
1233    PowerManagerInternal mLocalPowerManager;
1234
1235    /**
1236     * We want to hold a wake lock while running a voice interaction session, since
1237     * this may happen with the screen off and we need to keep the CPU running to
1238     * be able to continue to interact with the user.
1239     */
1240    PowerManager.WakeLock mVoiceWakeLock;
1241
1242    /**
1243     * State of external calls telling us if the device is awake or asleep.
1244     */
1245    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1246
1247    /**
1248     * A list of tokens that cause the top activity to be put to sleep.
1249     * They are used by components that may hide and block interaction with underlying
1250     * activities.
1251     */
1252    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1253
1254    static final int LOCK_SCREEN_HIDDEN = 0;
1255    static final int LOCK_SCREEN_LEAVING = 1;
1256    static final int LOCK_SCREEN_SHOWN = 2;
1257    /**
1258     * State of external call telling us if the lock screen is shown.
1259     */
1260    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1261
1262    /**
1263     * Set if we are shutting down the system, similar to sleeping.
1264     */
1265    boolean mShuttingDown = false;
1266
1267    /**
1268     * Current sequence id for oom_adj computation traversal.
1269     */
1270    int mAdjSeq = 0;
1271
1272    /**
1273     * Current sequence id for process LRU updating.
1274     */
1275    int mLruSeq = 0;
1276
1277    /**
1278     * Keep track of the non-cached/empty process we last found, to help
1279     * determine how to distribute cached/empty processes next time.
1280     */
1281    int mNumNonCachedProcs = 0;
1282
1283    /**
1284     * Keep track of the number of cached hidden procs, to balance oom adj
1285     * distribution between those and empty procs.
1286     */
1287    int mNumCachedHiddenProcs = 0;
1288
1289    /**
1290     * Keep track of the number of service processes we last found, to
1291     * determine on the next iteration which should be B services.
1292     */
1293    int mNumServiceProcs = 0;
1294    int mNewNumAServiceProcs = 0;
1295    int mNewNumServiceProcs = 0;
1296
1297    /**
1298     * Allow the current computed overall memory level of the system to go down?
1299     * This is set to false when we are killing processes for reasons other than
1300     * memory management, so that the now smaller process list will not be taken as
1301     * an indication that memory is tighter.
1302     */
1303    boolean mAllowLowerMemLevel = false;
1304
1305    /**
1306     * The last computed memory level, for holding when we are in a state that
1307     * processes are going away for other reasons.
1308     */
1309    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1310
1311    /**
1312     * The last total number of process we have, to determine if changes actually look
1313     * like a shrinking number of process due to lower RAM.
1314     */
1315    int mLastNumProcesses;
1316
1317    /**
1318     * The uptime of the last time we performed idle maintenance.
1319     */
1320    long mLastIdleTime = SystemClock.uptimeMillis();
1321
1322    /**
1323     * Total time spent with RAM that has been added in the past since the last idle time.
1324     */
1325    long mLowRamTimeSinceLastIdle = 0;
1326
1327    /**
1328     * If RAM is currently low, when that horrible situation started.
1329     */
1330    long mLowRamStartTime = 0;
1331
1332    /**
1333     * For reporting to battery stats the current top application.
1334     */
1335    private String mCurResumedPackage = null;
1336    private int mCurResumedUid = -1;
1337
1338    /**
1339     * For reporting to battery stats the apps currently running foreground
1340     * service.  The ProcessMap is package/uid tuples; each of these contain
1341     * an array of the currently foreground processes.
1342     */
1343    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1344            = new ProcessMap<ArrayList<ProcessRecord>>();
1345
1346    /**
1347     * This is set if we had to do a delayed dexopt of an app before launching
1348     * it, to increase the ANR timeouts in that case.
1349     */
1350    boolean mDidDexOpt;
1351
1352    /**
1353     * Set if the systemServer made a call to enterSafeMode.
1354     */
1355    boolean mSafeMode;
1356
1357    /**
1358     * If true, we are running under a test environment so will sample PSS from processes
1359     * much more rapidly to try to collect better data when the tests are rapidly
1360     * running through apps.
1361     */
1362    boolean mTestPssMode = false;
1363
1364    String mDebugApp = null;
1365    boolean mWaitForDebugger = false;
1366    boolean mDebugTransient = false;
1367    String mOrigDebugApp = null;
1368    boolean mOrigWaitForDebugger = false;
1369    boolean mAlwaysFinishActivities = false;
1370    boolean mLenientBackgroundCheck = false;
1371    boolean mForceResizableActivities;
1372    boolean mSupportsMultiWindow;
1373    boolean mSupportsFreeformWindowManagement;
1374    boolean mSupportsPictureInPicture;
1375    boolean mSupportsLeanbackOnly;
1376    IActivityController mController = null;
1377    boolean mControllerIsAMonkey = false;
1378    String mProfileApp = null;
1379    ProcessRecord mProfileProc = null;
1380    String mProfileFile;
1381    ParcelFileDescriptor mProfileFd;
1382    int mSamplingInterval = 0;
1383    boolean mAutoStopProfiler = false;
1384    int mProfileType = 0;
1385    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1386    String mMemWatchDumpProcName;
1387    String mMemWatchDumpFile;
1388    int mMemWatchDumpPid;
1389    int mMemWatchDumpUid;
1390    String mTrackAllocationApp = null;
1391    String mNativeDebuggingApp = null;
1392
1393    final long[] mTmpLong = new long[2];
1394
1395    // The size and position information that describes where the pinned stack will go by default.
1396    // In particular, the size is defined in DPs.
1397    Size mDefaultPinnedStackSizeDp;
1398    Size mDefaultPinnedStackScreenEdgeInsetsDp;
1399    int mDefaultPinnedStackGravity;
1400
1401    static final class ProcessChangeItem {
1402        static final int CHANGE_ACTIVITIES = 1<<0;
1403        static final int CHANGE_PROCESS_STATE = 1<<1;
1404        int changes;
1405        int uid;
1406        int pid;
1407        int processState;
1408        boolean foregroundActivities;
1409    }
1410
1411    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1412    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1413
1414    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1415    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1416
1417    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1418    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1419
1420    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1421    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1422
1423    /**
1424     * Runtime CPU use collection thread.  This object's lock is used to
1425     * perform synchronization with the thread (notifying it to run).
1426     */
1427    final Thread mProcessCpuThread;
1428
1429    /**
1430     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1431     * Must acquire this object's lock when accessing it.
1432     * NOTE: this lock will be held while doing long operations (trawling
1433     * through all processes in /proc), so it should never be acquired by
1434     * any critical paths such as when holding the main activity manager lock.
1435     */
1436    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1437            MONITOR_THREAD_CPU_USAGE);
1438    final AtomicLong mLastCpuTime = new AtomicLong(0);
1439    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1440
1441    long mLastWriteTime = 0;
1442
1443    /**
1444     * Used to retain an update lock when the foreground activity is in
1445     * immersive mode.
1446     */
1447    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1448
1449    /**
1450     * Set to true after the system has finished booting.
1451     */
1452    boolean mBooted = false;
1453
1454    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1455    int mProcessLimitOverride = -1;
1456
1457    WindowManagerService mWindowManager;
1458    final ActivityThread mSystemThread;
1459
1460    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1461        final ProcessRecord mApp;
1462        final int mPid;
1463        final IApplicationThread mAppThread;
1464
1465        AppDeathRecipient(ProcessRecord app, int pid,
1466                IApplicationThread thread) {
1467            if (DEBUG_ALL) Slog.v(
1468                TAG, "New death recipient " + this
1469                + " for thread " + thread.asBinder());
1470            mApp = app;
1471            mPid = pid;
1472            mAppThread = thread;
1473        }
1474
1475        @Override
1476        public void binderDied() {
1477            if (DEBUG_ALL) Slog.v(
1478                TAG, "Death received in " + this
1479                + " for thread " + mAppThread.asBinder());
1480            synchronized(ActivityManagerService.this) {
1481                appDiedLocked(mApp, mPid, mAppThread, true);
1482            }
1483        }
1484    }
1485
1486    static final int SHOW_ERROR_UI_MSG = 1;
1487    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1488    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1489    static final int UPDATE_CONFIGURATION_MSG = 4;
1490    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1491    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1492    static final int SERVICE_TIMEOUT_MSG = 12;
1493    static final int UPDATE_TIME_ZONE = 13;
1494    static final int SHOW_UID_ERROR_UI_MSG = 14;
1495    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1496    static final int PROC_START_TIMEOUT_MSG = 20;
1497    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1498    static final int KILL_APPLICATION_MSG = 22;
1499    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1500    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1501    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1502    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1503    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1504    static final int CLEAR_DNS_CACHE_MSG = 28;
1505    static final int UPDATE_HTTP_PROXY_MSG = 29;
1506    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1507    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1508    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1509    static final int REPORT_MEM_USAGE_MSG = 33;
1510    static final int REPORT_USER_SWITCH_MSG = 34;
1511    static final int CONTINUE_USER_SWITCH_MSG = 35;
1512    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1513    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1514    static final int PERSIST_URI_GRANTS_MSG = 38;
1515    static final int REQUEST_ALL_PSS_MSG = 39;
1516    static final int START_PROFILES_MSG = 40;
1517    static final int UPDATE_TIME = 41;
1518    static final int SYSTEM_USER_START_MSG = 42;
1519    static final int SYSTEM_USER_CURRENT_MSG = 43;
1520    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1521    static final int FINISH_BOOTING_MSG = 45;
1522    static final int START_USER_SWITCH_UI_MSG = 46;
1523    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1524    static final int DISMISS_DIALOG_UI_MSG = 48;
1525    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
1526    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
1527    static final int DELETE_DUMPHEAP_MSG = 51;
1528    static final int FOREGROUND_PROFILE_CHANGED_MSG = 52;
1529    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
1530    static final int REPORT_TIME_TRACKER_MSG = 54;
1531    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 55;
1532    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
1533    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
1534    static final int IDLE_UIDS_MSG = 58;
1535    static final int SYSTEM_USER_UNLOCK_MSG = 59;
1536    static final int LOG_STACK_STATE = 60;
1537    static final int VR_MODE_CHANGE_MSG = 61;
1538    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 62;
1539    static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 63;
1540    static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 64;
1541    static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 65;
1542    static final int START_USER_SWITCH_FG_MSG = 712;
1543
1544    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1545    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1546    static final int FIRST_COMPAT_MODE_MSG = 300;
1547    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1548
1549    static ServiceThread sKillThread = null;
1550    static KillHandler sKillHandler = null;
1551
1552    CompatModeDialog mCompatModeDialog;
1553    UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1554    long mLastMemUsageReportTime = 0;
1555
1556    /**
1557     * Flag whether the current user is a "monkey", i.e. whether
1558     * the UI is driven by a UI automation tool.
1559     */
1560    private boolean mUserIsMonkey;
1561
1562    /** Flag whether the device has a Recents UI */
1563    boolean mHasRecents;
1564
1565    /** The dimensions of the thumbnails in the Recents UI. */
1566    int mThumbnailWidth;
1567    int mThumbnailHeight;
1568    float mFullscreenThumbnailScale;
1569
1570    final ServiceThread mHandlerThread;
1571    final MainHandler mHandler;
1572    final UiHandler mUiHandler;
1573
1574    PackageManagerInternal mPackageManagerInt;
1575
1576    // VoiceInteraction session ID that changes for each new request except when
1577    // being called for multiwindow assist in a single session.
1578    private int mViSessionId = 1000;
1579
1580    final boolean mPermissionReviewRequired;
1581
1582    /**
1583     * Current global configuration information. Contains general settings for the entire system,
1584     * also corresponds to the merged configuration of the default display.
1585     */
1586    Configuration getGlobalConfiguration() {
1587        return mStackSupervisor.getConfiguration();
1588    }
1589
1590    final class KillHandler extends Handler {
1591        static final int KILL_PROCESS_GROUP_MSG = 4000;
1592
1593        public KillHandler(Looper looper) {
1594            super(looper, null, true);
1595        }
1596
1597        @Override
1598        public void handleMessage(Message msg) {
1599            switch (msg.what) {
1600                case KILL_PROCESS_GROUP_MSG:
1601                {
1602                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1603                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1604                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1605                }
1606                break;
1607
1608                default:
1609                    super.handleMessage(msg);
1610            }
1611        }
1612    }
1613
1614    final class UiHandler extends Handler {
1615        public UiHandler() {
1616            super(com.android.server.UiThread.get().getLooper(), null, true);
1617        }
1618
1619        @Override
1620        public void handleMessage(Message msg) {
1621            switch (msg.what) {
1622            case SHOW_ERROR_UI_MSG: {
1623                mAppErrors.handleShowAppErrorUi(msg);
1624                ensureBootCompleted();
1625            } break;
1626            case SHOW_NOT_RESPONDING_UI_MSG: {
1627                mAppErrors.handleShowAnrUi(msg);
1628                ensureBootCompleted();
1629            } break;
1630            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1631                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1632                synchronized (ActivityManagerService.this) {
1633                    ProcessRecord proc = (ProcessRecord) data.get("app");
1634                    if (proc == null) {
1635                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1636                        break;
1637                    }
1638                    if (proc.crashDialog != null) {
1639                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1640                        return;
1641                    }
1642                    AppErrorResult res = (AppErrorResult) data.get("result");
1643                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1644                        Dialog d = new StrictModeViolationDialog(mContext,
1645                                ActivityManagerService.this, res, proc);
1646                        d.show();
1647                        proc.crashDialog = d;
1648                    } else {
1649                        // The device is asleep, so just pretend that the user
1650                        // saw a crash dialog and hit "force quit".
1651                        res.set(0);
1652                    }
1653                }
1654                ensureBootCompleted();
1655            } break;
1656            case SHOW_FACTORY_ERROR_UI_MSG: {
1657                Dialog d = new FactoryErrorDialog(
1658                    mContext, msg.getData().getCharSequence("msg"));
1659                d.show();
1660                ensureBootCompleted();
1661            } break;
1662            case WAIT_FOR_DEBUGGER_UI_MSG: {
1663                synchronized (ActivityManagerService.this) {
1664                    ProcessRecord app = (ProcessRecord)msg.obj;
1665                    if (msg.arg1 != 0) {
1666                        if (!app.waitedForDebugger) {
1667                            Dialog d = new AppWaitingForDebuggerDialog(
1668                                    ActivityManagerService.this,
1669                                    mContext, app);
1670                            app.waitDialog = d;
1671                            app.waitedForDebugger = true;
1672                            d.show();
1673                        }
1674                    } else {
1675                        if (app.waitDialog != null) {
1676                            app.waitDialog.dismiss();
1677                            app.waitDialog = null;
1678                        }
1679                    }
1680                }
1681            } break;
1682            case SHOW_UID_ERROR_UI_MSG: {
1683                if (mShowDialogs) {
1684                    AlertDialog d = new BaseErrorDialog(mContext);
1685                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1686                    d.setCancelable(false);
1687                    d.setTitle(mContext.getText(R.string.android_system_label));
1688                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1689                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1690                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1691                    d.show();
1692                }
1693            } break;
1694            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1695                if (mShowDialogs) {
1696                    AlertDialog d = new BaseErrorDialog(mContext);
1697                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1698                    d.setCancelable(false);
1699                    d.setTitle(mContext.getText(R.string.android_system_label));
1700                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1701                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1702                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1703                    d.show();
1704                }
1705            } break;
1706            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1707                synchronized (ActivityManagerService.this) {
1708                    ActivityRecord ar = (ActivityRecord) msg.obj;
1709                    if (mCompatModeDialog != null) {
1710                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1711                                ar.info.applicationInfo.packageName)) {
1712                            return;
1713                        }
1714                        mCompatModeDialog.dismiss();
1715                        mCompatModeDialog = null;
1716                    }
1717                    if (ar != null && false) {
1718                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1719                                ar.packageName)) {
1720                            int mode = mCompatModePackages.computeCompatModeLocked(
1721                                    ar.info.applicationInfo);
1722                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1723                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1724                                mCompatModeDialog = new CompatModeDialog(
1725                                        ActivityManagerService.this, mContext,
1726                                        ar.info.applicationInfo);
1727                                mCompatModeDialog.show();
1728                            }
1729                        }
1730                    }
1731                }
1732                break;
1733            }
1734            case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1735                synchronized (ActivityManagerService.this) {
1736                    final ActivityRecord ar = (ActivityRecord) msg.obj;
1737                    if (mUnsupportedDisplaySizeDialog != null) {
1738                        mUnsupportedDisplaySizeDialog.dismiss();
1739                        mUnsupportedDisplaySizeDialog = null;
1740                    }
1741                    if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1742                            ar.packageName)) {
1743                        // TODO(multi-display): Show dialog on appropriate display.
1744                        mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1745                                ActivityManagerService.this, mContext, ar.info.applicationInfo);
1746                        mUnsupportedDisplaySizeDialog.show();
1747                    }
1748                }
1749                break;
1750            }
1751            case START_USER_SWITCH_UI_MSG: {
1752                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1753                break;
1754            }
1755            case DISMISS_DIALOG_UI_MSG: {
1756                final Dialog d = (Dialog) msg.obj;
1757                d.dismiss();
1758                break;
1759            }
1760            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1761                dispatchProcessesChanged();
1762                break;
1763            }
1764            case DISPATCH_PROCESS_DIED_UI_MSG: {
1765                final int pid = msg.arg1;
1766                final int uid = msg.arg2;
1767                dispatchProcessDied(pid, uid);
1768                break;
1769            }
1770            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1771                dispatchUidsChanged();
1772            } break;
1773            }
1774        }
1775    }
1776
1777    final class MainHandler extends Handler {
1778        public MainHandler(Looper looper) {
1779            super(looper, null, true);
1780        }
1781
1782        @Override
1783        public void handleMessage(Message msg) {
1784            switch (msg.what) {
1785            case UPDATE_CONFIGURATION_MSG: {
1786                final ContentResolver resolver = mContext.getContentResolver();
1787                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1788                        msg.arg1);
1789            } break;
1790            case GC_BACKGROUND_PROCESSES_MSG: {
1791                synchronized (ActivityManagerService.this) {
1792                    performAppGcsIfAppropriateLocked();
1793                }
1794            } break;
1795            case SERVICE_TIMEOUT_MSG: {
1796                if (mDidDexOpt) {
1797                    mDidDexOpt = false;
1798                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1799                    nmsg.obj = msg.obj;
1800                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1801                    return;
1802                }
1803                mServices.serviceTimeout((ProcessRecord)msg.obj);
1804            } break;
1805            case UPDATE_TIME_ZONE: {
1806                synchronized (ActivityManagerService.this) {
1807                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1808                        ProcessRecord r = mLruProcesses.get(i);
1809                        if (r.thread != null) {
1810                            try {
1811                                r.thread.updateTimeZone();
1812                            } catch (RemoteException ex) {
1813                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1814                            }
1815                        }
1816                    }
1817                }
1818            } break;
1819            case CLEAR_DNS_CACHE_MSG: {
1820                synchronized (ActivityManagerService.this) {
1821                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1822                        ProcessRecord r = mLruProcesses.get(i);
1823                        if (r.thread != null) {
1824                            try {
1825                                r.thread.clearDnsCache();
1826                            } catch (RemoteException ex) {
1827                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1828                            }
1829                        }
1830                    }
1831                }
1832            } break;
1833            case UPDATE_HTTP_PROXY_MSG: {
1834                ProxyInfo proxy = (ProxyInfo)msg.obj;
1835                String host = "";
1836                String port = "";
1837                String exclList = "";
1838                Uri pacFileUrl = Uri.EMPTY;
1839                if (proxy != null) {
1840                    host = proxy.getHost();
1841                    port = Integer.toString(proxy.getPort());
1842                    exclList = proxy.getExclusionListAsString();
1843                    pacFileUrl = proxy.getPacFileUrl();
1844                }
1845                synchronized (ActivityManagerService.this) {
1846                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1847                        ProcessRecord r = mLruProcesses.get(i);
1848                        if (r.thread != null) {
1849                            try {
1850                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1851                            } catch (RemoteException ex) {
1852                                Slog.w(TAG, "Failed to update http proxy for: " +
1853                                        r.info.processName);
1854                            }
1855                        }
1856                    }
1857                }
1858            } break;
1859            case PROC_START_TIMEOUT_MSG: {
1860                if (mDidDexOpt) {
1861                    mDidDexOpt = false;
1862                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1863                    nmsg.obj = msg.obj;
1864                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1865                    return;
1866                }
1867                ProcessRecord app = (ProcessRecord)msg.obj;
1868                synchronized (ActivityManagerService.this) {
1869                    processStartTimedOutLocked(app);
1870                }
1871            } break;
1872            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1873                ProcessRecord app = (ProcessRecord)msg.obj;
1874                synchronized (ActivityManagerService.this) {
1875                    processContentProviderPublishTimedOutLocked(app);
1876                }
1877            } break;
1878            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1879                synchronized (ActivityManagerService.this) {
1880                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1881                }
1882            } break;
1883            case KILL_APPLICATION_MSG: {
1884                synchronized (ActivityManagerService.this) {
1885                    final int appId = msg.arg1;
1886                    final int userId = msg.arg2;
1887                    Bundle bundle = (Bundle)msg.obj;
1888                    String pkg = bundle.getString("pkg");
1889                    String reason = bundle.getString("reason");
1890                    forceStopPackageLocked(pkg, appId, false, false, true, false,
1891                            false, userId, reason);
1892                }
1893            } break;
1894            case FINALIZE_PENDING_INTENT_MSG: {
1895                ((PendingIntentRecord)msg.obj).completeFinalize();
1896            } break;
1897            case POST_HEAVY_NOTIFICATION_MSG: {
1898                INotificationManager inm = NotificationManager.getService();
1899                if (inm == null) {
1900                    return;
1901                }
1902
1903                ActivityRecord root = (ActivityRecord)msg.obj;
1904                ProcessRecord process = root.app;
1905                if (process == null) {
1906                    return;
1907                }
1908
1909                try {
1910                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1911                    String text = mContext.getString(R.string.heavy_weight_notification,
1912                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1913                    Notification notification = new Notification.Builder(context)
1914                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1915                            .setWhen(0)
1916                            .setOngoing(true)
1917                            .setTicker(text)
1918                            .setColor(mContext.getColor(
1919                                    com.android.internal.R.color.system_notification_accent_color))
1920                            .setContentTitle(text)
1921                            .setContentText(
1922                                    mContext.getText(R.string.heavy_weight_notification_detail))
1923                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1924                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1925                                    new UserHandle(root.userId)))
1926                            .build();
1927                    try {
1928                        int[] outId = new int[1];
1929                        inm.enqueueNotificationWithTag("android", "android", null,
1930                                R.string.heavy_weight_notification,
1931                                notification, outId, root.userId);
1932                    } catch (RuntimeException e) {
1933                        Slog.w(ActivityManagerService.TAG,
1934                                "Error showing notification for heavy-weight app", e);
1935                    } catch (RemoteException e) {
1936                    }
1937                } catch (NameNotFoundException e) {
1938                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1939                }
1940            } break;
1941            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1942                INotificationManager inm = NotificationManager.getService();
1943                if (inm == null) {
1944                    return;
1945                }
1946                try {
1947                    inm.cancelNotificationWithTag("android", null,
1948                            R.string.heavy_weight_notification,  msg.arg1);
1949                } catch (RuntimeException e) {
1950                    Slog.w(ActivityManagerService.TAG,
1951                            "Error canceling notification for service", e);
1952                } catch (RemoteException e) {
1953                }
1954            } break;
1955            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1956                synchronized (ActivityManagerService.this) {
1957                    checkExcessivePowerUsageLocked(true);
1958                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1959                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1960                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1961                }
1962            } break;
1963            case REPORT_MEM_USAGE_MSG: {
1964                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1965                Thread thread = new Thread() {
1966                    @Override public void run() {
1967                        reportMemUsage(memInfos);
1968                    }
1969                };
1970                thread.start();
1971                break;
1972            }
1973            case START_USER_SWITCH_FG_MSG: {
1974                mUserController.startUserInForeground(msg.arg1);
1975                break;
1976            }
1977            case REPORT_USER_SWITCH_MSG: {
1978                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1979                break;
1980            }
1981            case CONTINUE_USER_SWITCH_MSG: {
1982                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1983                break;
1984            }
1985            case USER_SWITCH_TIMEOUT_MSG: {
1986                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1987                break;
1988            }
1989            case IMMERSIVE_MODE_LOCK_MSG: {
1990                final boolean nextState = (msg.arg1 != 0);
1991                if (mUpdateLock.isHeld() != nextState) {
1992                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1993                            "Applying new update lock state '" + nextState
1994                            + "' for " + (ActivityRecord)msg.obj);
1995                    if (nextState) {
1996                        mUpdateLock.acquire();
1997                    } else {
1998                        mUpdateLock.release();
1999                    }
2000                }
2001                break;
2002            }
2003            case PERSIST_URI_GRANTS_MSG: {
2004                writeGrantedUriPermissions();
2005                break;
2006            }
2007            case REQUEST_ALL_PSS_MSG: {
2008                synchronized (ActivityManagerService.this) {
2009                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
2010                }
2011                break;
2012            }
2013            case START_PROFILES_MSG: {
2014                synchronized (ActivityManagerService.this) {
2015                    mUserController.startProfilesLocked();
2016                }
2017                break;
2018            }
2019            case UPDATE_TIME: {
2020                synchronized (ActivityManagerService.this) {
2021                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2022                        ProcessRecord r = mLruProcesses.get(i);
2023                        if (r.thread != null) {
2024                            try {
2025                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
2026                            } catch (RemoteException ex) {
2027                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
2028                            }
2029                        }
2030                    }
2031                }
2032                break;
2033            }
2034            case SYSTEM_USER_START_MSG: {
2035                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2036                        Integer.toString(msg.arg1), msg.arg1);
2037                mSystemServiceManager.startUser(msg.arg1);
2038                break;
2039            }
2040            case SYSTEM_USER_UNLOCK_MSG: {
2041                final int userId = msg.arg1;
2042                mSystemServiceManager.unlockUser(userId);
2043                synchronized (ActivityManagerService.this) {
2044                    mRecentTasks.loadUserRecentsLocked(userId);
2045                }
2046                if (userId == UserHandle.USER_SYSTEM) {
2047                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2048                }
2049                installEncryptionUnawareProviders(userId);
2050                mUserController.finishUserUnlocked((UserState) msg.obj);
2051                break;
2052            }
2053            case SYSTEM_USER_CURRENT_MSG: {
2054                mBatteryStatsService.noteEvent(
2055                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2056                        Integer.toString(msg.arg2), msg.arg2);
2057                mBatteryStatsService.noteEvent(
2058                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2059                        Integer.toString(msg.arg1), msg.arg1);
2060                mSystemServiceManager.switchUser(msg.arg1);
2061                break;
2062            }
2063            case ENTER_ANIMATION_COMPLETE_MSG: {
2064                synchronized (ActivityManagerService.this) {
2065                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2066                    if (r != null && r.app != null && r.app.thread != null) {
2067                        try {
2068                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2069                        } catch (RemoteException e) {
2070                        }
2071                    }
2072                }
2073                break;
2074            }
2075            case FINISH_BOOTING_MSG: {
2076                if (msg.arg1 != 0) {
2077                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2078                    finishBooting();
2079                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2080                }
2081                if (msg.arg2 != 0) {
2082                    enableScreenAfterBoot();
2083                }
2084                break;
2085            }
2086            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2087                try {
2088                    Locale l = (Locale) msg.obj;
2089                    IBinder service = ServiceManager.getService("mount");
2090                    IMountService mountService = IMountService.Stub.asInterface(service);
2091                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2092                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2093                } catch (RemoteException e) {
2094                    Log.e(TAG, "Error storing locale for decryption UI", e);
2095                }
2096                break;
2097            }
2098            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2099                final int uid = msg.arg1;
2100                final byte[] firstPacket = (byte[]) msg.obj;
2101
2102                synchronized (mPidsSelfLocked) {
2103                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2104                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2105                        if (p.uid == uid) {
2106                            try {
2107                                p.thread.notifyCleartextNetwork(firstPacket);
2108                            } catch (RemoteException ignored) {
2109                            }
2110                        }
2111                    }
2112                }
2113                break;
2114            }
2115            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2116                final String procName;
2117                final int uid;
2118                final long memLimit;
2119                final String reportPackage;
2120                synchronized (ActivityManagerService.this) {
2121                    procName = mMemWatchDumpProcName;
2122                    uid = mMemWatchDumpUid;
2123                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2124                    if (val == null) {
2125                        val = mMemWatchProcesses.get(procName, 0);
2126                    }
2127                    if (val != null) {
2128                        memLimit = val.first;
2129                        reportPackage = val.second;
2130                    } else {
2131                        memLimit = 0;
2132                        reportPackage = null;
2133                    }
2134                }
2135                if (procName == null) {
2136                    return;
2137                }
2138
2139                if (DEBUG_PSS) Slog.d(TAG_PSS,
2140                        "Showing dump heap notification from " + procName + "/" + uid);
2141
2142                INotificationManager inm = NotificationManager.getService();
2143                if (inm == null) {
2144                    return;
2145                }
2146
2147                String text = mContext.getString(R.string.dump_heap_notification, procName);
2148
2149
2150                Intent deleteIntent = new Intent();
2151                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2152                Intent intent = new Intent();
2153                intent.setClassName("android", DumpHeapActivity.class.getName());
2154                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2155                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2156                if (reportPackage != null) {
2157                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2158                }
2159                int userId = UserHandle.getUserId(uid);
2160                Notification notification = new Notification.Builder(mContext)
2161                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2162                        .setWhen(0)
2163                        .setOngoing(true)
2164                        .setAutoCancel(true)
2165                        .setTicker(text)
2166                        .setColor(mContext.getColor(
2167                                com.android.internal.R.color.system_notification_accent_color))
2168                        .setContentTitle(text)
2169                        .setContentText(
2170                                mContext.getText(R.string.dump_heap_notification_detail))
2171                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2172                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2173                                new UserHandle(userId)))
2174                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2175                                deleteIntent, 0, UserHandle.SYSTEM))
2176                        .build();
2177
2178                try {
2179                    int[] outId = new int[1];
2180                    inm.enqueueNotificationWithTag("android", "android", null,
2181                            R.string.dump_heap_notification,
2182                            notification, outId, userId);
2183                } catch (RuntimeException e) {
2184                    Slog.w(ActivityManagerService.TAG,
2185                            "Error showing notification for dump heap", e);
2186                } catch (RemoteException e) {
2187                }
2188            } break;
2189            case DELETE_DUMPHEAP_MSG: {
2190                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2191                        DumpHeapActivity.JAVA_URI,
2192                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2193                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2194                        UserHandle.myUserId());
2195                synchronized (ActivityManagerService.this) {
2196                    mMemWatchDumpFile = null;
2197                    mMemWatchDumpProcName = null;
2198                    mMemWatchDumpPid = -1;
2199                    mMemWatchDumpUid = -1;
2200                }
2201            } break;
2202            case FOREGROUND_PROFILE_CHANGED_MSG: {
2203                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2204            } break;
2205            case REPORT_TIME_TRACKER_MSG: {
2206                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2207                tracker.deliverResult(mContext);
2208            } break;
2209            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2210                mUserController.dispatchUserSwitchComplete(msg.arg1);
2211            } break;
2212            case REPORT_LOCKED_BOOT_COMPLETE_MSG: {
2213                mUserController.dispatchLockedBootComplete(msg.arg1);
2214            } break;
2215            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2216                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2217                try {
2218                    connection.shutdown();
2219                } catch (RemoteException e) {
2220                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2221                }
2222                // Only a UiAutomation can set this flag and now that
2223                // it is finished we make sure it is reset to its default.
2224                mUserIsMonkey = false;
2225            } break;
2226            case IDLE_UIDS_MSG: {
2227                idleUids();
2228            } break;
2229            case VR_MODE_CHANGE_MSG: {
2230                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2231                if (vrService == null) {
2232                    break;
2233                }
2234                final ActivityRecord r = (ActivityRecord) msg.obj;
2235                boolean vrMode;
2236                ComponentName requestedPackage;
2237                ComponentName callingPackage;
2238                int userId;
2239                synchronized (ActivityManagerService.this) {
2240                    vrMode = r.requestedVrComponent != null;
2241                    requestedPackage = r.requestedVrComponent;
2242                    userId = r.userId;
2243                    callingPackage = r.info.getComponentName();
2244                    if (mInVrMode != vrMode) {
2245                        mInVrMode = vrMode;
2246                        mShowDialogs = shouldShowDialogs(getGlobalConfiguration(), mInVrMode);
2247                        if (r.app != null) {
2248                            ProcessRecord proc = r.app;
2249                            if (proc.vrThreadTid > 0) {
2250                                if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
2251                                    try {
2252                                        if (mInVrMode == true) {
2253                                            Process.setThreadScheduler(proc.vrThreadTid,
2254                                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
2255                                        } else {
2256                                            Process.setThreadScheduler(proc.vrThreadTid,
2257                                                Process.SCHED_OTHER, 0);
2258                                        }
2259                                    } catch (IllegalArgumentException e) {
2260                                        Slog.w(TAG, "Failed to set scheduling policy, thread does"
2261                                                + " not exist:\n" + e);
2262                                    }
2263                                }
2264                            }
2265                        }
2266                    }
2267                }
2268                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2269            } break;
2270            case VR_MODE_APPLY_IF_NEEDED_MSG: {
2271                final ActivityRecord r = (ActivityRecord) msg.obj;
2272                final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2273                if (needsVrMode) {
2274                    applyVrMode(msg.arg1 == 1, r.requestedVrComponent, r.userId,
2275                            r.info.getComponentName(), false);
2276                }
2277            } break;
2278            case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
2279                synchronized (ActivityManagerService.this) {
2280                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2281                        ProcessRecord r = mLruProcesses.get(i);
2282                        if (r.thread != null) {
2283                            try {
2284                                r.thread.handleTrustStorageUpdate();
2285                            } catch (RemoteException ex) {
2286                                Slog.w(TAG, "Failed to handle trust storage update for: " +
2287                                        r.info.processName);
2288                            }
2289                        }
2290                    }
2291                }
2292            } break;
2293            }
2294        }
2295    };
2296
2297    static final int COLLECT_PSS_BG_MSG = 1;
2298
2299    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2300        @Override
2301        public void handleMessage(Message msg) {
2302            switch (msg.what) {
2303            case COLLECT_PSS_BG_MSG: {
2304                long start = SystemClock.uptimeMillis();
2305                MemInfoReader memInfo = null;
2306                synchronized (ActivityManagerService.this) {
2307                    if (mFullPssPending) {
2308                        mFullPssPending = false;
2309                        memInfo = new MemInfoReader();
2310                    }
2311                }
2312                if (memInfo != null) {
2313                    updateCpuStatsNow();
2314                    long nativeTotalPss = 0;
2315                    final List<ProcessCpuTracker.Stats> stats;
2316                    synchronized (mProcessCpuTracker) {
2317                        stats = mProcessCpuTracker.getStats( (st)-> {
2318                            return st.vsize > 0 && st.uid < Process.FIRST_APPLICATION_UID;
2319                        });
2320                    }
2321                    final int N = stats.size();
2322                    for (int j = 0; j < N; j++) {
2323                        synchronized (mPidsSelfLocked) {
2324                            if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2325                                // This is one of our own processes; skip it.
2326                                continue;
2327                            }
2328                        }
2329                        nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2330                    }
2331                    memInfo.readMemInfo();
2332                    synchronized (ActivityManagerService.this) {
2333                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2334                                + (SystemClock.uptimeMillis()-start) + "ms");
2335                        final long cachedKb = memInfo.getCachedSizeKb();
2336                        final long freeKb = memInfo.getFreeSizeKb();
2337                        final long zramKb = memInfo.getZramTotalSizeKb();
2338                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2339                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2340                                kernelKb*1024, nativeTotalPss*1024);
2341                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2342                                nativeTotalPss);
2343                    }
2344                }
2345
2346                int num = 0;
2347                long[] tmp = new long[2];
2348                do {
2349                    ProcessRecord proc;
2350                    int procState;
2351                    int pid;
2352                    long lastPssTime;
2353                    synchronized (ActivityManagerService.this) {
2354                        if (mPendingPssProcesses.size() <= 0) {
2355                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2356                                    "Collected PSS of " + num + " processes in "
2357                                    + (SystemClock.uptimeMillis() - start) + "ms");
2358                            mPendingPssProcesses.clear();
2359                            return;
2360                        }
2361                        proc = mPendingPssProcesses.remove(0);
2362                        procState = proc.pssProcState;
2363                        lastPssTime = proc.lastPssTime;
2364                        if (proc.thread != null && procState == proc.setProcState
2365                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2366                                        < SystemClock.uptimeMillis()) {
2367                            pid = proc.pid;
2368                        } else {
2369                            proc = null;
2370                            pid = 0;
2371                        }
2372                    }
2373                    if (proc != null) {
2374                        long pss = Debug.getPss(pid, tmp, null);
2375                        synchronized (ActivityManagerService.this) {
2376                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2377                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2378                                num++;
2379                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2380                                        SystemClock.uptimeMillis());
2381                            }
2382                        }
2383                    }
2384                } while (true);
2385            }
2386            }
2387        }
2388    };
2389
2390    public void setSystemProcess() {
2391        try {
2392            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2393            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2394            ServiceManager.addService("meminfo", new MemBinder(this));
2395            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2396            ServiceManager.addService("dbinfo", new DbBinder(this));
2397            if (MONITOR_CPU_USAGE) {
2398                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2399            }
2400            ServiceManager.addService("permission", new PermissionController(this));
2401            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2402
2403            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2404                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2405            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2406
2407            synchronized (this) {
2408                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2409                app.persistent = true;
2410                app.pid = MY_PID;
2411                app.maxAdj = ProcessList.SYSTEM_ADJ;
2412                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2413                synchronized (mPidsSelfLocked) {
2414                    mPidsSelfLocked.put(app.pid, app);
2415                }
2416                updateLruProcessLocked(app, false, null);
2417                updateOomAdjLocked();
2418            }
2419        } catch (PackageManager.NameNotFoundException e) {
2420            throw new RuntimeException(
2421                    "Unable to find android system package", e);
2422        }
2423    }
2424
2425    public void setWindowManager(WindowManagerService wm) {
2426        mWindowManager = wm;
2427        mStackSupervisor.setWindowManager(wm);
2428        mActivityStarter.setWindowManager(wm);
2429    }
2430
2431    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2432        mUsageStatsService = usageStatsManager;
2433    }
2434
2435    public void startObservingNativeCrashes() {
2436        final NativeCrashListener ncl = new NativeCrashListener(this);
2437        ncl.start();
2438    }
2439
2440    public IAppOpsService getAppOpsService() {
2441        return mAppOpsService;
2442    }
2443
2444    static class MemBinder extends Binder {
2445        ActivityManagerService mActivityManagerService;
2446        MemBinder(ActivityManagerService activityManagerService) {
2447            mActivityManagerService = activityManagerService;
2448        }
2449
2450        @Override
2451        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2452            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2453                    != PackageManager.PERMISSION_GRANTED) {
2454                pw.println("Permission Denial: can't dump meminfo from from pid="
2455                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2456                        + " without permission " + android.Manifest.permission.DUMP);
2457                return;
2458            }
2459
2460            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2461        }
2462    }
2463
2464    static class GraphicsBinder extends Binder {
2465        ActivityManagerService mActivityManagerService;
2466        GraphicsBinder(ActivityManagerService activityManagerService) {
2467            mActivityManagerService = activityManagerService;
2468        }
2469
2470        @Override
2471        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2472            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2473                    != PackageManager.PERMISSION_GRANTED) {
2474                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2475                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2476                        + " without permission " + android.Manifest.permission.DUMP);
2477                return;
2478            }
2479
2480            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2481        }
2482    }
2483
2484    static class DbBinder extends Binder {
2485        ActivityManagerService mActivityManagerService;
2486        DbBinder(ActivityManagerService activityManagerService) {
2487            mActivityManagerService = activityManagerService;
2488        }
2489
2490        @Override
2491        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2492            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2493                    != PackageManager.PERMISSION_GRANTED) {
2494                pw.println("Permission Denial: can't dump dbinfo from from pid="
2495                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2496                        + " without permission " + android.Manifest.permission.DUMP);
2497                return;
2498            }
2499
2500            mActivityManagerService.dumpDbInfo(fd, pw, args);
2501        }
2502    }
2503
2504    static class CpuBinder extends Binder {
2505        ActivityManagerService mActivityManagerService;
2506        CpuBinder(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 cpuinfo from from pid="
2515                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2516                        + " without permission " + android.Manifest.permission.DUMP);
2517                return;
2518            }
2519
2520            synchronized (mActivityManagerService.mProcessCpuTracker) {
2521                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2522                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2523                        SystemClock.uptimeMillis()));
2524            }
2525        }
2526    }
2527
2528    public static final class Lifecycle extends SystemService {
2529        private final ActivityManagerService mService;
2530
2531        public Lifecycle(Context context) {
2532            super(context);
2533            mService = new ActivityManagerService(context);
2534        }
2535
2536        @Override
2537        public void onStart() {
2538            mService.start();
2539        }
2540
2541        public ActivityManagerService getService() {
2542            return mService;
2543        }
2544    }
2545
2546    // Note: This method is invoked on the main thread but may need to attach various
2547    // handlers to other threads.  So take care to be explicit about the looper.
2548    public ActivityManagerService(Context systemContext) {
2549        mContext = systemContext;
2550        mFactoryTest = FactoryTest.getMode();
2551        mSystemThread = ActivityThread.currentActivityThread();
2552
2553        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2554
2555        mPermissionReviewRequired = mContext.getResources().getBoolean(
2556                com.android.internal.R.bool.config_permissionReviewRequired);
2557
2558        mHandlerThread = new ServiceThread(TAG,
2559                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2560        mHandlerThread.start();
2561        mHandler = new MainHandler(mHandlerThread.getLooper());
2562        mUiHandler = new UiHandler();
2563
2564        /* static; one-time init here */
2565        if (sKillHandler == null) {
2566            sKillThread = new ServiceThread(TAG + ":kill",
2567                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2568            sKillThread.start();
2569            sKillHandler = new KillHandler(sKillThread.getLooper());
2570        }
2571
2572        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2573                "foreground", BROADCAST_FG_TIMEOUT, false);
2574        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2575                "background", BROADCAST_BG_TIMEOUT, true);
2576        mBroadcastQueues[0] = mFgBroadcastQueue;
2577        mBroadcastQueues[1] = mBgBroadcastQueue;
2578
2579        mServices = new ActiveServices(this);
2580        mProviderMap = new ProviderMap(this);
2581        mAppErrors = new AppErrors(mContext, this);
2582
2583        // TODO: Move creation of battery stats service outside of activity manager service.
2584        File dataDir = Environment.getDataDirectory();
2585        File systemDir = new File(dataDir, "system");
2586        systemDir.mkdirs();
2587        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2588        mBatteryStatsService.getActiveStatistics().readLocked();
2589        mBatteryStatsService.scheduleWriteToDisk();
2590        mOnBattery = DEBUG_POWER ? true
2591                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2592        mBatteryStatsService.getActiveStatistics().setCallback(this);
2593
2594        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2595
2596        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2597        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2598                new IAppOpsCallback.Stub() {
2599                    @Override public void opChanged(int op, int uid, String packageName) {
2600                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2601                            if (mAppOpsService.checkOperation(op, uid, packageName)
2602                                    != AppOpsManager.MODE_ALLOWED) {
2603                                runInBackgroundDisabled(uid);
2604                            }
2605                        }
2606                    }
2607                });
2608
2609        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2610
2611        mUserController = new UserController(this);
2612
2613        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2614            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2615
2616        if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2617            mUseFifoUiScheduling = true;
2618        }
2619
2620        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2621
2622        mTempConfig.setToDefaults();
2623        mTempConfig.setLocales(LocaleList.getDefault());
2624        mConfigurationSeq = mTempConfig.seq = 1;
2625
2626        mProcessCpuTracker.init();
2627
2628        mStackSupervisor = new ActivityStackSupervisor(this);
2629        mStackSupervisor.onConfigurationChanged(mTempConfig);
2630        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2631        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2632        mTaskChangeNotificationController =
2633                new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
2634        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2635        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2636
2637        mProcessCpuThread = new Thread("CpuTracker") {
2638            @Override
2639            public void run() {
2640                while (true) {
2641                    try {
2642                        try {
2643                            synchronized(this) {
2644                                final long now = SystemClock.uptimeMillis();
2645                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2646                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2647                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2648                                //        + ", write delay=" + nextWriteDelay);
2649                                if (nextWriteDelay < nextCpuDelay) {
2650                                    nextCpuDelay = nextWriteDelay;
2651                                }
2652                                if (nextCpuDelay > 0) {
2653                                    mProcessCpuMutexFree.set(true);
2654                                    this.wait(nextCpuDelay);
2655                                }
2656                            }
2657                        } catch (InterruptedException e) {
2658                        }
2659                        updateCpuStatsNow();
2660                    } catch (Exception e) {
2661                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2662                    }
2663                }
2664            }
2665        };
2666
2667        Watchdog.getInstance().addMonitor(this);
2668        Watchdog.getInstance().addThread(mHandler);
2669    }
2670
2671    public void setSystemServiceManager(SystemServiceManager mgr) {
2672        mSystemServiceManager = mgr;
2673    }
2674
2675    public void setInstaller(Installer installer) {
2676        mInstaller = installer;
2677    }
2678
2679    private void start() {
2680        Process.removeAllProcessGroups();
2681        mProcessCpuThread.start();
2682
2683        mBatteryStatsService.publish(mContext);
2684        mAppOpsService.publish(mContext);
2685        Slog.d("AppOps", "AppOpsService published");
2686        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2687    }
2688
2689    void onUserStoppedLocked(int userId) {
2690        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2691    }
2692
2693    public void initPowerManagement() {
2694        mStackSupervisor.initPowerManagement();
2695        mBatteryStatsService.initPowerManagement();
2696        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2697        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2698        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2699        mVoiceWakeLock.setReferenceCounted(false);
2700    }
2701
2702    @Override
2703    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2704            throws RemoteException {
2705        if (code == SYSPROPS_TRANSACTION) {
2706            // We need to tell all apps about the system property change.
2707            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2708            synchronized(this) {
2709                final int NP = mProcessNames.getMap().size();
2710                for (int ip=0; ip<NP; ip++) {
2711                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2712                    final int NA = apps.size();
2713                    for (int ia=0; ia<NA; ia++) {
2714                        ProcessRecord app = apps.valueAt(ia);
2715                        if (app.thread != null) {
2716                            procs.add(app.thread.asBinder());
2717                        }
2718                    }
2719                }
2720            }
2721
2722            int N = procs.size();
2723            for (int i=0; i<N; i++) {
2724                Parcel data2 = Parcel.obtain();
2725                try {
2726                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2727                } catch (RemoteException e) {
2728                }
2729                data2.recycle();
2730            }
2731        }
2732        try {
2733            return super.onTransact(code, data, reply, flags);
2734        } catch (RuntimeException e) {
2735            // The activity manager only throws security exceptions, so let's
2736            // log all others.
2737            if (!(e instanceof SecurityException)) {
2738                Slog.wtf(TAG, "Activity Manager Crash", e);
2739            }
2740            throw e;
2741        }
2742    }
2743
2744    void updateCpuStats() {
2745        final long now = SystemClock.uptimeMillis();
2746        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2747            return;
2748        }
2749        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2750            synchronized (mProcessCpuThread) {
2751                mProcessCpuThread.notify();
2752            }
2753        }
2754    }
2755
2756    void updateCpuStatsNow() {
2757        synchronized (mProcessCpuTracker) {
2758            mProcessCpuMutexFree.set(false);
2759            final long now = SystemClock.uptimeMillis();
2760            boolean haveNewCpuStats = false;
2761
2762            if (MONITOR_CPU_USAGE &&
2763                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2764                mLastCpuTime.set(now);
2765                mProcessCpuTracker.update();
2766                if (mProcessCpuTracker.hasGoodLastStats()) {
2767                    haveNewCpuStats = true;
2768                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2769                    //Slog.i(TAG, "Total CPU usage: "
2770                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2771
2772                    // Slog the cpu usage if the property is set.
2773                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2774                        int user = mProcessCpuTracker.getLastUserTime();
2775                        int system = mProcessCpuTracker.getLastSystemTime();
2776                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2777                        int irq = mProcessCpuTracker.getLastIrqTime();
2778                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2779                        int idle = mProcessCpuTracker.getLastIdleTime();
2780
2781                        int total = user + system + iowait + irq + softIrq + idle;
2782                        if (total == 0) total = 1;
2783
2784                        EventLog.writeEvent(EventLogTags.CPU,
2785                                ((user+system+iowait+irq+softIrq) * 100) / total,
2786                                (user * 100) / total,
2787                                (system * 100) / total,
2788                                (iowait * 100) / total,
2789                                (irq * 100) / total,
2790                                (softIrq * 100) / total);
2791                    }
2792                }
2793            }
2794
2795            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2796            synchronized(bstats) {
2797                synchronized(mPidsSelfLocked) {
2798                    if (haveNewCpuStats) {
2799                        if (bstats.startAddingCpuLocked()) {
2800                            int totalUTime = 0;
2801                            int totalSTime = 0;
2802                            final int N = mProcessCpuTracker.countStats();
2803                            for (int i=0; i<N; i++) {
2804                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2805                                if (!st.working) {
2806                                    continue;
2807                                }
2808                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2809                                totalUTime += st.rel_utime;
2810                                totalSTime += st.rel_stime;
2811                                if (pr != null) {
2812                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2813                                    if (ps == null || !ps.isActive()) {
2814                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2815                                                pr.info.uid, pr.processName);
2816                                    }
2817                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2818                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2819                                } else {
2820                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2821                                    if (ps == null || !ps.isActive()) {
2822                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2823                                                bstats.mapUid(st.uid), st.name);
2824                                    }
2825                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2826                                }
2827                            }
2828                            final int userTime = mProcessCpuTracker.getLastUserTime();
2829                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2830                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2831                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2832                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2833                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2834                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2835                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2836                        }
2837                    }
2838                }
2839
2840                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2841                    mLastWriteTime = now;
2842                    mBatteryStatsService.scheduleWriteToDisk();
2843                }
2844            }
2845        }
2846    }
2847
2848    @Override
2849    public void batteryNeedsCpuUpdate() {
2850        updateCpuStatsNow();
2851    }
2852
2853    @Override
2854    public void batteryPowerChanged(boolean onBattery) {
2855        // When plugging in, update the CPU stats first before changing
2856        // the plug state.
2857        updateCpuStatsNow();
2858        synchronized (this) {
2859            synchronized(mPidsSelfLocked) {
2860                mOnBattery = DEBUG_POWER ? true : onBattery;
2861            }
2862        }
2863    }
2864
2865    @Override
2866    public void batterySendBroadcast(Intent intent) {
2867        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2868                AppOpsManager.OP_NONE, null, false, false,
2869                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2870    }
2871
2872    /**
2873     * Initialize the application bind args. These are passed to each
2874     * process when the bindApplication() IPC is sent to the process. They're
2875     * lazily setup to make sure the services are running when they're asked for.
2876     */
2877    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2878        // Isolated processes won't get this optimization, so that we don't
2879        // violate the rules about which services they have access to.
2880        if (isolated) {
2881            if (mIsolatedAppBindArgs == null) {
2882                mIsolatedAppBindArgs = new HashMap<>();
2883                mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
2884            }
2885            return mIsolatedAppBindArgs;
2886        }
2887
2888        if (mAppBindArgs == null) {
2889            mAppBindArgs = new HashMap<>();
2890
2891            // Setup the application init args
2892            mAppBindArgs.put("package", ServiceManager.getService("package"));
2893            mAppBindArgs.put("window", ServiceManager.getService("window"));
2894            mAppBindArgs.put(Context.ALARM_SERVICE,
2895                    ServiceManager.getService(Context.ALARM_SERVICE));
2896        }
2897        return mAppBindArgs;
2898    }
2899
2900    /**
2901     * Update AMS states when an activity is resumed. This should only be called by
2902     * {@link ActivityStack#setResumedActivityLocked} when an activity is resumed.
2903     */
2904    void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
2905        if (r.task.isApplicationTask()) {
2906            if (mCurAppTimeTracker != r.appTimeTracker) {
2907                // We are switching app tracking.  Complete the current one.
2908                if (mCurAppTimeTracker != null) {
2909                    mCurAppTimeTracker.stop();
2910                    mHandler.obtainMessage(
2911                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2912                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2913                    mCurAppTimeTracker = null;
2914                }
2915                if (r.appTimeTracker != null) {
2916                    mCurAppTimeTracker = r.appTimeTracker;
2917                    startTimeTrackingFocusedActivityLocked();
2918                }
2919            } else {
2920                startTimeTrackingFocusedActivityLocked();
2921            }
2922        } else {
2923            r.appTimeTracker = null;
2924        }
2925        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2926        // TODO: Probably not, because we don't want to resume voice on switching
2927        // back to this activity
2928        if (r.task.voiceInteractor != null) {
2929            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2930        } else {
2931            finishRunningVoiceLocked();
2932            IVoiceInteractionSession session;
2933            if (mLastResumedActivity != null
2934                    && ((session = mLastResumedActivity.task.voiceSession) != null
2935                    || (session = mLastResumedActivity.voiceSession) != null)) {
2936                // We had been in a voice interaction session, but now focused has
2937                // move to something different.  Just finish the session, we can't
2938                // return to it and retain the proper state and synchronization with
2939                // the voice interaction service.
2940                finishVoiceTask(session);
2941            }
2942        }
2943
2944        mWindowManager.setFocusedApp(r.appToken, true);
2945
2946        applyUpdateLockStateLocked(r);
2947        applyUpdateVrModeLocked(r);
2948        if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
2949            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2950            mHandler.obtainMessage(
2951                    FOREGROUND_PROFILE_CHANGED_MSG, r.userId, 0).sendToTarget();
2952        }
2953
2954        mLastResumedActivity = r;
2955
2956        EventLogTags.writeAmSetResumedActivity(
2957                r == null ? -1 : r.userId,
2958                r == null ? "NULL" : r.shortComponentName,
2959                reason);
2960    }
2961
2962    @Override
2963    public void setFocusedStack(int stackId) {
2964        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
2965        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2966        final long callingId = Binder.clearCallingIdentity();
2967        try {
2968            synchronized (this) {
2969                final ActivityStack stack = mStackSupervisor.getStack(stackId);
2970                if (stack == null) {
2971                    return;
2972                }
2973                final ActivityRecord r = stack.topRunningActivityLocked();
2974                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
2975                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
2976                }
2977            }
2978        } finally {
2979            Binder.restoreCallingIdentity(callingId);
2980        }
2981    }
2982
2983    @Override
2984    public void setFocusedTask(int taskId) {
2985        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
2986        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
2987        final long callingId = Binder.clearCallingIdentity();
2988        try {
2989            synchronized (this) {
2990                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2991                if (task == null) {
2992                    return;
2993                }
2994                final ActivityRecord r = task.topRunningActivityLocked();
2995                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
2996                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
2997                }
2998            }
2999        } finally {
3000            Binder.restoreCallingIdentity(callingId);
3001        }
3002    }
3003
3004    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3005    @Override
3006    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3007        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3008        mTaskChangeNotificationController.registerTaskStackListener(listener);
3009    }
3010
3011    /**
3012     * Unregister a task stack listener so that it stops receiving callbacks.
3013     */
3014    @Override
3015    public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
3016         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "unregisterTaskStackListener()");
3017         mTaskChangeNotificationController.unregisterTaskStackListener(listener);
3018     }
3019
3020    @Override
3021    public void notifyActivityDrawn(IBinder token) {
3022        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3023        synchronized (this) {
3024            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3025            if (r != null) {
3026                r.getStack().notifyActivityDrawnLocked(r);
3027            }
3028        }
3029    }
3030
3031    final void applyUpdateLockStateLocked(ActivityRecord r) {
3032        // Modifications to the UpdateLock state are done on our handler, outside
3033        // the activity manager's locks.  The new state is determined based on the
3034        // state *now* of the relevant activity record.  The object is passed to
3035        // the handler solely for logging detail, not to be consulted/modified.
3036        final boolean nextState = r != null && r.immersive;
3037        mHandler.sendMessage(
3038                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3039    }
3040
3041    final void applyUpdateVrModeLocked(ActivityRecord r) {
3042        mHandler.sendMessage(
3043                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3044    }
3045
3046    private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3047        mHandler.sendMessage(
3048                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3049    }
3050
3051    private void applyVrMode(boolean enabled, ComponentName packageName, int userId,
3052            ComponentName callingPackage, boolean immediate) {
3053        VrManagerInternal vrService =
3054                LocalServices.getService(VrManagerInternal.class);
3055        if (immediate) {
3056            vrService.setVrModeImmediate(enabled, packageName, userId, callingPackage);
3057        } else {
3058            vrService.setVrMode(enabled, packageName, userId, callingPackage);
3059        }
3060    }
3061
3062    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3063        Message msg = Message.obtain();
3064        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3065        msg.obj = r.task.askedCompatMode ? null : r;
3066        mUiHandler.sendMessage(msg);
3067    }
3068
3069    final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3070        final Configuration globalConfig = getGlobalConfiguration();
3071        if (globalConfig.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3072                && r.appInfo.requiresSmallestWidthDp > globalConfig.smallestScreenWidthDp) {
3073            final Message msg = Message.obtain();
3074            msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3075            msg.obj = r;
3076            mUiHandler.sendMessage(msg);
3077        }
3078    }
3079
3080    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3081            String what, Object obj, ProcessRecord srcApp) {
3082        app.lastActivityTime = now;
3083
3084        if (app.activities.size() > 0) {
3085            // Don't want to touch dependent processes that are hosting activities.
3086            return index;
3087        }
3088
3089        int lrui = mLruProcesses.lastIndexOf(app);
3090        if (lrui < 0) {
3091            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3092                    + what + " " + obj + " from " + srcApp);
3093            return index;
3094        }
3095
3096        if (lrui >= index) {
3097            // Don't want to cause this to move dependent processes *back* in the
3098            // list as if they were less frequently used.
3099            return index;
3100        }
3101
3102        if (lrui >= mLruProcessActivityStart) {
3103            // Don't want to touch dependent processes that are hosting activities.
3104            return index;
3105        }
3106
3107        mLruProcesses.remove(lrui);
3108        if (index > 0) {
3109            index--;
3110        }
3111        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3112                + " in LRU list: " + app);
3113        mLruProcesses.add(index, app);
3114        return index;
3115    }
3116
3117    static void killProcessGroup(int uid, int pid) {
3118        if (sKillHandler != null) {
3119            sKillHandler.sendMessage(
3120                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3121        } else {
3122            Slog.w(TAG, "Asked to kill process group before system bringup!");
3123            Process.killProcessGroup(uid, pid);
3124        }
3125    }
3126
3127    final void removeLruProcessLocked(ProcessRecord app) {
3128        int lrui = mLruProcesses.lastIndexOf(app);
3129        if (lrui >= 0) {
3130            if (!app.killed) {
3131                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3132                Process.killProcessQuiet(app.pid);
3133                killProcessGroup(app.uid, app.pid);
3134            }
3135            if (lrui <= mLruProcessActivityStart) {
3136                mLruProcessActivityStart--;
3137            }
3138            if (lrui <= mLruProcessServiceStart) {
3139                mLruProcessServiceStart--;
3140            }
3141            mLruProcesses.remove(lrui);
3142        }
3143    }
3144
3145    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3146            ProcessRecord client) {
3147        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3148                || app.treatLikeActivity;
3149        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3150        if (!activityChange && hasActivity) {
3151            // The process has activities, so we are only allowing activity-based adjustments
3152            // to move it.  It should be kept in the front of the list with other
3153            // processes that have activities, and we don't want those to change their
3154            // order except due to activity operations.
3155            return;
3156        }
3157
3158        mLruSeq++;
3159        final long now = SystemClock.uptimeMillis();
3160        app.lastActivityTime = now;
3161
3162        // First a quick reject: if the app is already at the position we will
3163        // put it, then there is nothing to do.
3164        if (hasActivity) {
3165            final int N = mLruProcesses.size();
3166            if (N > 0 && mLruProcesses.get(N-1) == app) {
3167                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3168                return;
3169            }
3170        } else {
3171            if (mLruProcessServiceStart > 0
3172                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3173                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3174                return;
3175            }
3176        }
3177
3178        int lrui = mLruProcesses.lastIndexOf(app);
3179
3180        if (app.persistent && lrui >= 0) {
3181            // We don't care about the position of persistent processes, as long as
3182            // they are in the list.
3183            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3184            return;
3185        }
3186
3187        /* In progress: compute new position first, so we can avoid doing work
3188           if the process is not actually going to move.  Not yet working.
3189        int addIndex;
3190        int nextIndex;
3191        boolean inActivity = false, inService = false;
3192        if (hasActivity) {
3193            // Process has activities, put it at the very tipsy-top.
3194            addIndex = mLruProcesses.size();
3195            nextIndex = mLruProcessServiceStart;
3196            inActivity = true;
3197        } else if (hasService) {
3198            // Process has services, put it at the top of the service list.
3199            addIndex = mLruProcessActivityStart;
3200            nextIndex = mLruProcessServiceStart;
3201            inActivity = true;
3202            inService = true;
3203        } else  {
3204            // Process not otherwise of interest, it goes to the top of the non-service area.
3205            addIndex = mLruProcessServiceStart;
3206            if (client != null) {
3207                int clientIndex = mLruProcesses.lastIndexOf(client);
3208                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3209                        + app);
3210                if (clientIndex >= 0 && addIndex > clientIndex) {
3211                    addIndex = clientIndex;
3212                }
3213            }
3214            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3215        }
3216
3217        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3218                + mLruProcessActivityStart + "): " + app);
3219        */
3220
3221        if (lrui >= 0) {
3222            if (lrui < mLruProcessActivityStart) {
3223                mLruProcessActivityStart--;
3224            }
3225            if (lrui < mLruProcessServiceStart) {
3226                mLruProcessServiceStart--;
3227            }
3228            /*
3229            if (addIndex > lrui) {
3230                addIndex--;
3231            }
3232            if (nextIndex > lrui) {
3233                nextIndex--;
3234            }
3235            */
3236            mLruProcesses.remove(lrui);
3237        }
3238
3239        /*
3240        mLruProcesses.add(addIndex, app);
3241        if (inActivity) {
3242            mLruProcessActivityStart++;
3243        }
3244        if (inService) {
3245            mLruProcessActivityStart++;
3246        }
3247        */
3248
3249        int nextIndex;
3250        if (hasActivity) {
3251            final int N = mLruProcesses.size();
3252            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3253                // Process doesn't have activities, but has clients with
3254                // activities...  move it up, but one below the top (the top
3255                // should always have a real activity).
3256                if (DEBUG_LRU) Slog.d(TAG_LRU,
3257                        "Adding to second-top of LRU activity list: " + app);
3258                mLruProcesses.add(N - 1, app);
3259                // To keep it from spamming the LRU list (by making a bunch of clients),
3260                // we will push down any other entries owned by the app.
3261                final int uid = app.info.uid;
3262                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3263                    ProcessRecord subProc = mLruProcesses.get(i);
3264                    if (subProc.info.uid == uid) {
3265                        // We want to push this one down the list.  If the process after
3266                        // it is for the same uid, however, don't do so, because we don't
3267                        // want them internally to be re-ordered.
3268                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3269                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3270                                    "Pushing uid " + uid + " swapping at " + i + ": "
3271                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3272                            ProcessRecord tmp = mLruProcesses.get(i);
3273                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3274                            mLruProcesses.set(i - 1, tmp);
3275                            i--;
3276                        }
3277                    } else {
3278                        // A gap, we can stop here.
3279                        break;
3280                    }
3281                }
3282            } else {
3283                // Process has activities, put it at the very tipsy-top.
3284                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3285                mLruProcesses.add(app);
3286            }
3287            nextIndex = mLruProcessServiceStart;
3288        } else if (hasService) {
3289            // Process has services, put it at the top of the service list.
3290            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3291            mLruProcesses.add(mLruProcessActivityStart, app);
3292            nextIndex = mLruProcessServiceStart;
3293            mLruProcessActivityStart++;
3294        } else  {
3295            // Process not otherwise of interest, it goes to the top of the non-service area.
3296            int index = mLruProcessServiceStart;
3297            if (client != null) {
3298                // If there is a client, don't allow the process to be moved up higher
3299                // in the list than that client.
3300                int clientIndex = mLruProcesses.lastIndexOf(client);
3301                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3302                        + " when updating " + app);
3303                if (clientIndex <= lrui) {
3304                    // Don't allow the client index restriction to push it down farther in the
3305                    // list than it already is.
3306                    clientIndex = lrui;
3307                }
3308                if (clientIndex >= 0 && index > clientIndex) {
3309                    index = clientIndex;
3310                }
3311            }
3312            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3313            mLruProcesses.add(index, app);
3314            nextIndex = index-1;
3315            mLruProcessActivityStart++;
3316            mLruProcessServiceStart++;
3317        }
3318
3319        // If the app is currently using a content provider or service,
3320        // bump those processes as well.
3321        for (int j=app.connections.size()-1; j>=0; j--) {
3322            ConnectionRecord cr = app.connections.valueAt(j);
3323            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3324                    && cr.binding.service.app != null
3325                    && cr.binding.service.app.lruSeq != mLruSeq
3326                    && !cr.binding.service.app.persistent) {
3327                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3328                        "service connection", cr, app);
3329            }
3330        }
3331        for (int j=app.conProviders.size()-1; j>=0; j--) {
3332            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3333            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3334                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3335                        "provider reference", cpr, app);
3336            }
3337        }
3338    }
3339
3340    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3341        if (uid == Process.SYSTEM_UID) {
3342            // The system gets to run in any process.  If there are multiple
3343            // processes with the same uid, just pick the first (this
3344            // should never happen).
3345            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3346            if (procs == null) return null;
3347            final int procCount = procs.size();
3348            for (int i = 0; i < procCount; i++) {
3349                final int procUid = procs.keyAt(i);
3350                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3351                    // Don't use an app process or different user process for system component.
3352                    continue;
3353                }
3354                return procs.valueAt(i);
3355            }
3356        }
3357        ProcessRecord proc = mProcessNames.get(processName, uid);
3358        if (false && proc != null && !keepIfLarge
3359                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3360                && proc.lastCachedPss >= 4000) {
3361            // Turn this condition on to cause killing to happen regularly, for testing.
3362            if (proc.baseProcessTracker != null) {
3363                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3364            }
3365            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3366        } else if (proc != null && !keepIfLarge
3367                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3368                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3369            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3370            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3371                if (proc.baseProcessTracker != null) {
3372                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3373                }
3374                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3375            }
3376        }
3377        return proc;
3378    }
3379
3380    void notifyPackageUse(String packageName, int reason) {
3381        IPackageManager pm = AppGlobals.getPackageManager();
3382        try {
3383            pm.notifyPackageUse(packageName, reason);
3384        } catch (RemoteException e) {
3385        }
3386    }
3387
3388    boolean isNextTransitionForward() {
3389        int transit = mWindowManager.getPendingAppTransition();
3390        return transit == TRANSIT_ACTIVITY_OPEN
3391                || transit == TRANSIT_TASK_OPEN
3392                || transit == TRANSIT_TASK_TO_FRONT;
3393    }
3394
3395    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3396            String processName, String abiOverride, int uid, Runnable crashHandler) {
3397        synchronized(this) {
3398            ApplicationInfo info = new ApplicationInfo();
3399            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3400            // For isolated processes, the former contains the parent's uid and the latter the
3401            // actual uid of the isolated process.
3402            // In the special case introduced by this method (which is, starting an isolated
3403            // process directly from the SystemServer without an actual parent app process) the
3404            // closest thing to a parent's uid is SYSTEM_UID.
3405            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3406            // the |isolated| logic in the ProcessRecord constructor.
3407            info.uid = Process.SYSTEM_UID;
3408            info.processName = processName;
3409            info.className = entryPoint;
3410            info.packageName = "android";
3411            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3412                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3413                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3414                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3415                    crashHandler);
3416            return proc != null ? proc.pid : 0;
3417        }
3418    }
3419
3420    final ProcessRecord startProcessLocked(String processName,
3421            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3422            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3423            boolean isolated, boolean keepIfLarge) {
3424        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3425                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3426                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3427                null /* crashHandler */);
3428    }
3429
3430    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3431            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3432            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3433            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3434        long startTime = SystemClock.elapsedRealtime();
3435        ProcessRecord app;
3436        if (!isolated) {
3437            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3438            checkTime(startTime, "startProcess: after getProcessRecord");
3439
3440            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3441                // If we are in the background, then check to see if this process
3442                // is bad.  If so, we will just silently fail.
3443                if (mAppErrors.isBadProcessLocked(info)) {
3444                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3445                            + "/" + info.processName);
3446                    return null;
3447                }
3448            } else {
3449                // When the user is explicitly starting a process, then clear its
3450                // crash count so that we won't make it bad until they see at
3451                // least one crash dialog again, and make the process good again
3452                // if it had been bad.
3453                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3454                        + "/" + info.processName);
3455                mAppErrors.resetProcessCrashTimeLocked(info);
3456                if (mAppErrors.isBadProcessLocked(info)) {
3457                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3458                            UserHandle.getUserId(info.uid), info.uid,
3459                            info.processName);
3460                    mAppErrors.clearBadProcessLocked(info);
3461                    if (app != null) {
3462                        app.bad = false;
3463                    }
3464                }
3465            }
3466        } else {
3467            // If this is an isolated process, it can't re-use an existing process.
3468            app = null;
3469        }
3470
3471        // We don't have to do anything more if:
3472        // (1) There is an existing application record; and
3473        // (2) The caller doesn't think it is dead, OR there is no thread
3474        //     object attached to it so we know it couldn't have crashed; and
3475        // (3) There is a pid assigned to it, so it is either starting or
3476        //     already running.
3477        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3478                + " app=" + app + " knownToBeDead=" + knownToBeDead
3479                + " thread=" + (app != null ? app.thread : null)
3480                + " pid=" + (app != null ? app.pid : -1));
3481        if (app != null && app.pid > 0) {
3482            if ((!knownToBeDead && !app.killed) || app.thread == null) {
3483                // We already have the app running, or are waiting for it to
3484                // come up (we have a pid but not yet its thread), so keep it.
3485                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3486                // If this is a new package in the process, add the package to the list
3487                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3488                checkTime(startTime, "startProcess: done, added package to proc");
3489                return app;
3490            }
3491
3492            // An application record is attached to a previous process,
3493            // clean it up now.
3494            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3495            checkTime(startTime, "startProcess: bad proc running, killing");
3496            killProcessGroup(app.uid, app.pid);
3497            handleAppDiedLocked(app, true, true);
3498            checkTime(startTime, "startProcess: done killing old proc");
3499        }
3500
3501        String hostingNameStr = hostingName != null
3502                ? hostingName.flattenToShortString() : null;
3503
3504        if (app == null) {
3505            checkTime(startTime, "startProcess: creating new process record");
3506            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3507            if (app == null) {
3508                Slog.w(TAG, "Failed making new process record for "
3509                        + processName + "/" + info.uid + " isolated=" + isolated);
3510                return null;
3511            }
3512            app.crashHandler = crashHandler;
3513            checkTime(startTime, "startProcess: done creating new process record");
3514        } else {
3515            // If this is a new package in the process, add the package to the list
3516            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3517            checkTime(startTime, "startProcess: added package to existing proc");
3518        }
3519
3520        // If the system is not ready yet, then hold off on starting this
3521        // process until it is.
3522        if (!mProcessesReady
3523                && !isAllowedWhileBooting(info)
3524                && !allowWhileBooting) {
3525            if (!mProcessesOnHold.contains(app)) {
3526                mProcessesOnHold.add(app);
3527            }
3528            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3529                    "System not ready, putting on hold: " + app);
3530            checkTime(startTime, "startProcess: returning with proc on hold");
3531            return app;
3532        }
3533
3534        checkTime(startTime, "startProcess: stepping in to startProcess");
3535        startProcessLocked(
3536                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3537        checkTime(startTime, "startProcess: done starting proc!");
3538        return (app.pid != 0) ? app : null;
3539    }
3540
3541    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3542        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3543    }
3544
3545    private final void startProcessLocked(ProcessRecord app,
3546            String hostingType, String hostingNameStr) {
3547        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3548                null /* entryPoint */, null /* entryPointArgs */);
3549    }
3550
3551    private final void startProcessLocked(ProcessRecord app, String hostingType,
3552            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3553        long startTime = SystemClock.elapsedRealtime();
3554        if (app.pid > 0 && app.pid != MY_PID) {
3555            checkTime(startTime, "startProcess: removing from pids map");
3556            synchronized (mPidsSelfLocked) {
3557                mPidsSelfLocked.remove(app.pid);
3558                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3559            }
3560            checkTime(startTime, "startProcess: done removing from pids map");
3561            app.setPid(0);
3562        }
3563
3564        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3565                "startProcessLocked removing on hold: " + app);
3566        mProcessesOnHold.remove(app);
3567
3568        checkTime(startTime, "startProcess: starting to update cpu stats");
3569        updateCpuStats();
3570        checkTime(startTime, "startProcess: done updating cpu stats");
3571
3572        try {
3573            try {
3574                final int userId = UserHandle.getUserId(app.uid);
3575                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3576            } catch (RemoteException e) {
3577                throw e.rethrowAsRuntimeException();
3578            }
3579
3580            int uid = app.uid;
3581            int[] gids = null;
3582            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3583            if (!app.isolated) {
3584                int[] permGids = null;
3585                try {
3586                    checkTime(startTime, "startProcess: getting gids from package manager");
3587                    final IPackageManager pm = AppGlobals.getPackageManager();
3588                    permGids = pm.getPackageGids(app.info.packageName,
3589                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3590                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3591                            MountServiceInternal.class);
3592                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3593                            app.info.packageName);
3594                } catch (RemoteException e) {
3595                    throw e.rethrowAsRuntimeException();
3596                }
3597
3598                /*
3599                 * Add shared application and profile GIDs so applications can share some
3600                 * resources like shared libraries and access user-wide resources
3601                 */
3602                if (ArrayUtils.isEmpty(permGids)) {
3603                    gids = new int[2];
3604                } else {
3605                    gids = new int[permGids.length + 2];
3606                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3607                }
3608                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3609                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3610            }
3611            checkTime(startTime, "startProcess: building args");
3612            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3613                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3614                        && mTopComponent != null
3615                        && app.processName.equals(mTopComponent.getPackageName())) {
3616                    uid = 0;
3617                }
3618                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3619                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3620                    uid = 0;
3621                }
3622            }
3623            int debugFlags = 0;
3624            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3625                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3626                // Also turn on CheckJNI for debuggable apps. It's quite
3627                // awkward to turn on otherwise.
3628                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3629            }
3630            // Run the app in safe mode if its manifest requests so or the
3631            // system is booted in safe mode.
3632            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3633                mSafeMode == true) {
3634                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3635            }
3636            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3637                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3638            }
3639            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3640            if ("true".equals(genDebugInfoProperty)) {
3641                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3642            }
3643            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3644                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3645            }
3646            if ("1".equals(SystemProperties.get("debug.assert"))) {
3647                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3648            }
3649            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3650                // Enable all debug flags required by the native debugger.
3651                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3652                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3653                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3654                mNativeDebuggingApp = null;
3655            }
3656
3657            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3658            if (requiredAbi == null) {
3659                requiredAbi = Build.SUPPORTED_ABIS[0];
3660            }
3661
3662            String instructionSet = null;
3663            if (app.info.primaryCpuAbi != null) {
3664                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3665            }
3666
3667            app.gids = gids;
3668            app.requiredAbi = requiredAbi;
3669            app.instructionSet = instructionSet;
3670
3671            // Start the process.  It will either succeed and return a result containing
3672            // the PID of the new process, or else throw a RuntimeException.
3673            boolean isActivityProcess = (entryPoint == null);
3674            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3675            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3676                    app.processName);
3677            checkTime(startTime, "startProcess: asking zygote to start proc");
3678            Process.ProcessStartResult startResult = Process.start(entryPoint,
3679                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3680                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3681                    app.info.dataDir, entryPointArgs);
3682            checkTime(startTime, "startProcess: returned from zygote!");
3683            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3684
3685            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3686            checkTime(startTime, "startProcess: done updating battery stats");
3687
3688            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3689                    UserHandle.getUserId(uid), startResult.pid, uid,
3690                    app.processName, hostingType,
3691                    hostingNameStr != null ? hostingNameStr : "");
3692
3693            try {
3694                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3695                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3696            } catch (RemoteException ex) {
3697                // Ignore
3698            }
3699
3700            if (app.persistent) {
3701                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3702            }
3703
3704            checkTime(startTime, "startProcess: building log message");
3705            StringBuilder buf = mStringBuilder;
3706            buf.setLength(0);
3707            buf.append("Start proc ");
3708            buf.append(startResult.pid);
3709            buf.append(':');
3710            buf.append(app.processName);
3711            buf.append('/');
3712            UserHandle.formatUid(buf, uid);
3713            if (!isActivityProcess) {
3714                buf.append(" [");
3715                buf.append(entryPoint);
3716                buf.append("]");
3717            }
3718            buf.append(" for ");
3719            buf.append(hostingType);
3720            if (hostingNameStr != null) {
3721                buf.append(" ");
3722                buf.append(hostingNameStr);
3723            }
3724            Slog.i(TAG, buf.toString());
3725            app.setPid(startResult.pid);
3726            app.usingWrapper = startResult.usingWrapper;
3727            app.removed = false;
3728            app.killed = false;
3729            app.killedByAm = false;
3730            checkTime(startTime, "startProcess: starting to update pids map");
3731            ProcessRecord oldApp;
3732            synchronized (mPidsSelfLocked) {
3733                oldApp = mPidsSelfLocked.get(startResult.pid);
3734            }
3735            // If there is already an app occupying that pid that hasn't been cleaned up
3736            if (oldApp != null && !app.isolated) {
3737                // Clean up anything relating to this pid first
3738                Slog.w(TAG, "Reusing pid " + startResult.pid
3739                        + " while app is still mapped to it");
3740                cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3741                        true /*replacingPid*/);
3742            }
3743            synchronized (mPidsSelfLocked) {
3744                this.mPidsSelfLocked.put(startResult.pid, app);
3745                if (isActivityProcess) {
3746                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3747                    msg.obj = app;
3748                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3749                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3750                }
3751            }
3752            checkTime(startTime, "startProcess: done updating pids map");
3753        } catch (RuntimeException e) {
3754            Slog.e(TAG, "Failure starting process " + app.processName, e);
3755
3756            // Something went very wrong while trying to start this process; one
3757            // common case is when the package is frozen due to an active
3758            // upgrade. To recover, clean up any active bookkeeping related to
3759            // starting this process. (We already invoked this method once when
3760            // the package was initially frozen through KILL_APPLICATION_MSG, so
3761            // it doesn't hurt to use it again.)
3762            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3763                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3764        }
3765    }
3766
3767    void updateUsageStats(ActivityRecord component, boolean resumed) {
3768        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3769                "updateUsageStats: comp=" + component + "res=" + resumed);
3770        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3771        if (resumed) {
3772            if (mUsageStatsService != null) {
3773                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3774                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3775            }
3776            synchronized (stats) {
3777                stats.noteActivityResumedLocked(component.app.uid);
3778            }
3779        } else {
3780            if (mUsageStatsService != null) {
3781                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3782                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3783            }
3784            synchronized (stats) {
3785                stats.noteActivityPausedLocked(component.app.uid);
3786            }
3787        }
3788    }
3789
3790    Intent getHomeIntent() {
3791        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3792        intent.setComponent(mTopComponent);
3793        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3794        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3795            intent.addCategory(Intent.CATEGORY_HOME);
3796        }
3797        return intent;
3798    }
3799
3800    boolean startHomeActivityLocked(int userId, String reason) {
3801        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3802                && mTopAction == null) {
3803            // We are running in factory test mode, but unable to find
3804            // the factory test app, so just sit around displaying the
3805            // error message and don't try to start anything.
3806            return false;
3807        }
3808        Intent intent = getHomeIntent();
3809        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3810        if (aInfo != null) {
3811            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3812            // Don't do this if the home app is currently being
3813            // instrumented.
3814            aInfo = new ActivityInfo(aInfo);
3815            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3816            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3817                    aInfo.applicationInfo.uid, true);
3818            if (app == null || app.instrumentationClass == null) {
3819                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3820                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3821            }
3822        } else {
3823            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3824        }
3825
3826        return true;
3827    }
3828
3829    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3830        ActivityInfo ai = null;
3831        ComponentName comp = intent.getComponent();
3832        try {
3833            if (comp != null) {
3834                // Factory test.
3835                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3836            } else {
3837                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3838                        intent,
3839                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3840                        flags, userId);
3841
3842                if (info != null) {
3843                    ai = info.activityInfo;
3844                }
3845            }
3846        } catch (RemoteException e) {
3847            // ignore
3848        }
3849
3850        return ai;
3851    }
3852
3853    /**
3854     * Starts the "new version setup screen" if appropriate.
3855     */
3856    void startSetupActivityLocked() {
3857        // Only do this once per boot.
3858        if (mCheckedForSetup) {
3859            return;
3860        }
3861
3862        // We will show this screen if the current one is a different
3863        // version than the last one shown, and we are not running in
3864        // low-level factory test mode.
3865        final ContentResolver resolver = mContext.getContentResolver();
3866        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3867                Settings.Global.getInt(resolver,
3868                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3869            mCheckedForSetup = true;
3870
3871            // See if we should be showing the platform update setup UI.
3872            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3873            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3874                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3875            if (!ris.isEmpty()) {
3876                final ResolveInfo ri = ris.get(0);
3877                String vers = ri.activityInfo.metaData != null
3878                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3879                        : null;
3880                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3881                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3882                            Intent.METADATA_SETUP_VERSION);
3883                }
3884                String lastVers = Settings.Secure.getString(
3885                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3886                if (vers != null && !vers.equals(lastVers)) {
3887                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3888                    intent.setComponent(new ComponentName(
3889                            ri.activityInfo.packageName, ri.activityInfo.name));
3890                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3891                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3892                            null, 0, 0, 0, null, false, false, null, null, null);
3893                }
3894            }
3895        }
3896    }
3897
3898    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3899        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3900    }
3901
3902    void enforceNotIsolatedCaller(String caller) {
3903        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3904            throw new SecurityException("Isolated process not allowed to call " + caller);
3905        }
3906    }
3907
3908    void enforceShellRestriction(String restriction, int userHandle) {
3909        if (Binder.getCallingUid() == Process.SHELL_UID) {
3910            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3911                throw new SecurityException("Shell does not have permission to access user "
3912                        + userHandle);
3913            }
3914        }
3915    }
3916
3917    @Override
3918    public int getFrontActivityScreenCompatMode() {
3919        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3920        synchronized (this) {
3921            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3922        }
3923    }
3924
3925    @Override
3926    public void setFrontActivityScreenCompatMode(int mode) {
3927        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3928                "setFrontActivityScreenCompatMode");
3929        synchronized (this) {
3930            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3931        }
3932    }
3933
3934    @Override
3935    public int getPackageScreenCompatMode(String packageName) {
3936        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3937        synchronized (this) {
3938            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3939        }
3940    }
3941
3942    @Override
3943    public void setPackageScreenCompatMode(String packageName, int mode) {
3944        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3945                "setPackageScreenCompatMode");
3946        synchronized (this) {
3947            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3948        }
3949    }
3950
3951    @Override
3952    public boolean getPackageAskScreenCompat(String packageName) {
3953        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3954        synchronized (this) {
3955            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3956        }
3957    }
3958
3959    @Override
3960    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3961        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3962                "setPackageAskScreenCompat");
3963        synchronized (this) {
3964            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3965        }
3966    }
3967
3968    private boolean hasUsageStatsPermission(String callingPackage) {
3969        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3970                Binder.getCallingUid(), callingPackage);
3971        if (mode == AppOpsManager.MODE_DEFAULT) {
3972            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3973                    == PackageManager.PERMISSION_GRANTED;
3974        }
3975        return mode == AppOpsManager.MODE_ALLOWED;
3976    }
3977
3978    @Override
3979    public int getPackageProcessState(String packageName, String callingPackage) {
3980        if (!hasUsageStatsPermission(callingPackage)) {
3981            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
3982                    "getPackageProcessState");
3983        }
3984
3985        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3986        synchronized (this) {
3987            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3988                final ProcessRecord proc = mLruProcesses.get(i);
3989                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3990                        || procState > proc.setProcState) {
3991                    if (proc.pkgList.containsKey(packageName)) {
3992                        procState = proc.setProcState;
3993                        break;
3994                    }
3995                    if (proc.pkgDeps != null && proc.pkgDeps.contains(packageName)) {
3996                        procState = proc.setProcState;
3997                    }
3998                }
3999            }
4000        }
4001        return procState;
4002    }
4003
4004    @Override
4005    public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4006            throws RemoteException {
4007        synchronized (this) {
4008            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4009            if (app == null) {
4010                throw new IllegalArgumentException("Unknown process: " + process);
4011            }
4012            if (app.thread == null) {
4013                throw new IllegalArgumentException("Process has no app thread");
4014            }
4015            if (app.trimMemoryLevel >= level) {
4016                throw new IllegalArgumentException(
4017                        "Unable to set a higher trim level than current level");
4018            }
4019            if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4020                    app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4021                throw new IllegalArgumentException("Unable to set a background trim level "
4022                    + "on a foreground process");
4023            }
4024            app.thread.scheduleTrimMemory(level);
4025            app.trimMemoryLevel = level;
4026            return true;
4027        }
4028    }
4029
4030    private void dispatchProcessesChanged() {
4031        int N;
4032        synchronized (this) {
4033            N = mPendingProcessChanges.size();
4034            if (mActiveProcessChanges.length < N) {
4035                mActiveProcessChanges = new ProcessChangeItem[N];
4036            }
4037            mPendingProcessChanges.toArray(mActiveProcessChanges);
4038            mPendingProcessChanges.clear();
4039            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4040                    "*** Delivering " + N + " process changes");
4041        }
4042
4043        int i = mProcessObservers.beginBroadcast();
4044        while (i > 0) {
4045            i--;
4046            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4047            if (observer != null) {
4048                try {
4049                    for (int j=0; j<N; j++) {
4050                        ProcessChangeItem item = mActiveProcessChanges[j];
4051                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4052                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4053                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4054                                    + item.uid + ": " + item.foregroundActivities);
4055                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4056                                    item.foregroundActivities);
4057                        }
4058                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4059                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4060                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4061                                    + ": " + item.processState);
4062                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4063                        }
4064                    }
4065                } catch (RemoteException e) {
4066                }
4067            }
4068        }
4069        mProcessObservers.finishBroadcast();
4070
4071        synchronized (this) {
4072            for (int j=0; j<N; j++) {
4073                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4074            }
4075        }
4076    }
4077
4078    private void dispatchProcessDied(int pid, int uid) {
4079        int i = mProcessObservers.beginBroadcast();
4080        while (i > 0) {
4081            i--;
4082            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4083            if (observer != null) {
4084                try {
4085                    observer.onProcessDied(pid, uid);
4086                } catch (RemoteException e) {
4087                }
4088            }
4089        }
4090        mProcessObservers.finishBroadcast();
4091    }
4092
4093    private void dispatchUidsChanged() {
4094        int N;
4095        synchronized (this) {
4096            N = mPendingUidChanges.size();
4097            if (mActiveUidChanges.length < N) {
4098                mActiveUidChanges = new UidRecord.ChangeItem[N];
4099            }
4100            for (int i=0; i<N; i++) {
4101                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4102                mActiveUidChanges[i] = change;
4103                if (change.uidRecord != null) {
4104                    change.uidRecord.pendingChange = null;
4105                    change.uidRecord = null;
4106                }
4107            }
4108            mPendingUidChanges.clear();
4109            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4110                    "*** Delivering " + N + " uid changes");
4111        }
4112
4113        if (mLocalPowerManager != null) {
4114            for (int j=0; j<N; j++) {
4115                UidRecord.ChangeItem item = mActiveUidChanges[j];
4116                if (item.change == UidRecord.CHANGE_GONE
4117                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4118                    mLocalPowerManager.uidGone(item.uid);
4119                } else {
4120                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4121                }
4122            }
4123        }
4124
4125        int i = mUidObservers.beginBroadcast();
4126        while (i > 0) {
4127            i--;
4128            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4129            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4130            if (observer != null) {
4131                try {
4132                    for (int j=0; j<N; j++) {
4133                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4134                        final int change = item.change;
4135                        UidRecord validateUid = null;
4136                        if (VALIDATE_UID_STATES && i == 0) {
4137                            validateUid = mValidateUids.get(item.uid);
4138                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4139                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4140                                validateUid = new UidRecord(item.uid);
4141                                mValidateUids.put(item.uid, validateUid);
4142                            }
4143                        }
4144                        if (change == UidRecord.CHANGE_IDLE
4145                                || change == UidRecord.CHANGE_GONE_IDLE) {
4146                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4147                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4148                                        "UID idle uid=" + item.uid);
4149                                observer.onUidIdle(item.uid);
4150                            }
4151                            if (VALIDATE_UID_STATES && i == 0) {
4152                                if (validateUid != null) {
4153                                    validateUid.idle = true;
4154                                }
4155                            }
4156                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4157                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4158                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4159                                        "UID active uid=" + item.uid);
4160                                observer.onUidActive(item.uid);
4161                            }
4162                            if (VALIDATE_UID_STATES && i == 0) {
4163                                validateUid.idle = false;
4164                            }
4165                        }
4166                        if (change == UidRecord.CHANGE_GONE
4167                                || change == UidRecord.CHANGE_GONE_IDLE) {
4168                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4169                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4170                                        "UID gone uid=" + item.uid);
4171                                observer.onUidGone(item.uid);
4172                            }
4173                            if (VALIDATE_UID_STATES && i == 0) {
4174                                if (validateUid != null) {
4175                                    mValidateUids.remove(item.uid);
4176                                }
4177                            }
4178                        } else {
4179                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4180                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4181                                        "UID CHANGED uid=" + item.uid
4182                                                + ": " + item.processState);
4183                                observer.onUidStateChanged(item.uid, item.processState);
4184                            }
4185                            if (VALIDATE_UID_STATES && i == 0) {
4186                                validateUid.curProcState = validateUid.setProcState
4187                                        = item.processState;
4188                            }
4189                        }
4190                    }
4191                } catch (RemoteException e) {
4192                }
4193            }
4194        }
4195        mUidObservers.finishBroadcast();
4196
4197        synchronized (this) {
4198            for (int j=0; j<N; j++) {
4199                mAvailUidChanges.add(mActiveUidChanges[j]);
4200            }
4201        }
4202    }
4203
4204    @Override
4205    public final int startActivity(IApplicationThread caller, String callingPackage,
4206            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4207            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4208        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4209                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4210                UserHandle.getCallingUserId());
4211    }
4212
4213    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4214        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4215        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4216                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4217                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4218
4219        // TODO: Switch to user app stacks here.
4220        String mimeType = intent.getType();
4221        final Uri data = intent.getData();
4222        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4223            mimeType = getProviderMimeType(data, userId);
4224        }
4225        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4226
4227        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4228        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4229                null, 0, 0, null, null, null, null, false, userId, container, null);
4230    }
4231
4232    @Override
4233    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4234            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4235            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4236        enforceNotIsolatedCaller("startActivity");
4237        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4238                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4239        // TODO: Switch to user app stacks here.
4240        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4241                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4242                profilerInfo, null, null, bOptions, false, userId, null, null);
4243    }
4244
4245    @Override
4246    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4247            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4248            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4249            int userId) {
4250
4251        // This is very dangerous -- it allows you to perform a start activity (including
4252        // permission grants) as any app that may launch one of your own activities.  So
4253        // we will only allow this to be done from activities that are part of the core framework,
4254        // and then only when they are running as the system.
4255        final ActivityRecord sourceRecord;
4256        final int targetUid;
4257        final String targetPackage;
4258        synchronized (this) {
4259            if (resultTo == null) {
4260                throw new SecurityException("Must be called from an activity");
4261            }
4262            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4263            if (sourceRecord == null) {
4264                throw new SecurityException("Called with bad activity token: " + resultTo);
4265            }
4266            if (!sourceRecord.info.packageName.equals("android")) {
4267                throw new SecurityException(
4268                        "Must be called from an activity that is declared in the android package");
4269            }
4270            if (sourceRecord.app == null) {
4271                throw new SecurityException("Called without a process attached to activity");
4272            }
4273            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4274                // This is still okay, as long as this activity is running under the
4275                // uid of the original calling activity.
4276                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4277                    throw new SecurityException(
4278                            "Calling activity in uid " + sourceRecord.app.uid
4279                                    + " must be system uid or original calling uid "
4280                                    + sourceRecord.launchedFromUid);
4281                }
4282            }
4283            if (ignoreTargetSecurity) {
4284                if (intent.getComponent() == null) {
4285                    throw new SecurityException(
4286                            "Component must be specified with ignoreTargetSecurity");
4287                }
4288                if (intent.getSelector() != null) {
4289                    throw new SecurityException(
4290                            "Selector not allowed with ignoreTargetSecurity");
4291                }
4292            }
4293            targetUid = sourceRecord.launchedFromUid;
4294            targetPackage = sourceRecord.launchedFromPackage;
4295        }
4296
4297        if (userId == UserHandle.USER_NULL) {
4298            userId = UserHandle.getUserId(sourceRecord.app.uid);
4299        }
4300
4301        // TODO: Switch to user app stacks here.
4302        try {
4303            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4304                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4305                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4306            return ret;
4307        } catch (SecurityException e) {
4308            // XXX need to figure out how to propagate to original app.
4309            // A SecurityException here is generally actually a fault of the original
4310            // calling activity (such as a fairly granting permissions), so propagate it
4311            // back to them.
4312            /*
4313            StringBuilder msg = new StringBuilder();
4314            msg.append("While launching");
4315            msg.append(intent.toString());
4316            msg.append(": ");
4317            msg.append(e.getMessage());
4318            */
4319            throw e;
4320        }
4321    }
4322
4323    @Override
4324    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4325            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4326            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4327        enforceNotIsolatedCaller("startActivityAndWait");
4328        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4329                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4330        WaitResult res = new WaitResult();
4331        // TODO: Switch to user app stacks here.
4332        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4333                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4334                bOptions, false, userId, null, null);
4335        return res;
4336    }
4337
4338    @Override
4339    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4340            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4341            int startFlags, Configuration config, Bundle bOptions, int userId) {
4342        enforceNotIsolatedCaller("startActivityWithConfig");
4343        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4344                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4345        // TODO: Switch to user app stacks here.
4346        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4347                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4348                null, null, config, bOptions, false, userId, null, null);
4349        return ret;
4350    }
4351
4352    @Override
4353    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4354            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4355            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4356            throws TransactionTooLargeException {
4357        enforceNotIsolatedCaller("startActivityIntentSender");
4358        // Refuse possible leaked file descriptors
4359        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4360            throw new IllegalArgumentException("File descriptors passed in Intent");
4361        }
4362
4363        IIntentSender sender = intent.getTarget();
4364        if (!(sender instanceof PendingIntentRecord)) {
4365            throw new IllegalArgumentException("Bad PendingIntent object");
4366        }
4367
4368        PendingIntentRecord pir = (PendingIntentRecord)sender;
4369
4370        synchronized (this) {
4371            // If this is coming from the currently resumed activity, it is
4372            // effectively saying that app switches are allowed at this point.
4373            final ActivityStack stack = getFocusedStack();
4374            if (stack.mResumedActivity != null &&
4375                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4376                mAppSwitchesAllowedTime = 0;
4377            }
4378        }
4379        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4380                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4381        return ret;
4382    }
4383
4384    @Override
4385    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4386            Intent intent, String resolvedType, IVoiceInteractionSession session,
4387            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4388            Bundle bOptions, int userId) {
4389        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4390                != PackageManager.PERMISSION_GRANTED) {
4391            String msg = "Permission Denial: startVoiceActivity() from pid="
4392                    + Binder.getCallingPid()
4393                    + ", uid=" + Binder.getCallingUid()
4394                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4395            Slog.w(TAG, msg);
4396            throw new SecurityException(msg);
4397        }
4398        if (session == null || interactor == null) {
4399            throw new NullPointerException("null session or interactor");
4400        }
4401        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4402                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4403        // TODO: Switch to user app stacks here.
4404        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4405                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4406                null, bOptions, false, userId, null, null);
4407    }
4408
4409    @Override
4410    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4411            throws RemoteException {
4412        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4413        synchronized (this) {
4414            ActivityRecord activity = getFocusedStack().topActivity();
4415            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4416                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4417            }
4418            if (mRunningVoice != null || activity.task.voiceSession != null
4419                    || activity.voiceSession != null) {
4420                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4421                return;
4422            }
4423            if (activity.pendingVoiceInteractionStart) {
4424                Slog.w(TAG, "Pending start of voice interaction already.");
4425                return;
4426            }
4427            activity.pendingVoiceInteractionStart = true;
4428        }
4429        LocalServices.getService(VoiceInteractionManagerInternal.class)
4430                .startLocalVoiceInteraction(callingActivity, options);
4431    }
4432
4433    @Override
4434    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4435        LocalServices.getService(VoiceInteractionManagerInternal.class)
4436                .stopLocalVoiceInteraction(callingActivity);
4437    }
4438
4439    @Override
4440    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4441        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4442                .supportsLocalVoiceInteraction();
4443    }
4444
4445    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4446            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4447        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4448        if (activityToCallback == null) return;
4449        activityToCallback.setVoiceSessionLocked(voiceSession);
4450
4451        // Inform the activity
4452        try {
4453            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4454                    voiceInteractor);
4455            long token = Binder.clearCallingIdentity();
4456            try {
4457                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4458            } finally {
4459                Binder.restoreCallingIdentity(token);
4460            }
4461            // TODO: VI Should we cache the activity so that it's easier to find later
4462            // rather than scan through all the stacks and activities?
4463        } catch (RemoteException re) {
4464            activityToCallback.clearVoiceSessionLocked();
4465            // TODO: VI Should this terminate the voice session?
4466        }
4467    }
4468
4469    @Override
4470    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4471        synchronized (this) {
4472            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4473                if (keepAwake) {
4474                    mVoiceWakeLock.acquire();
4475                } else {
4476                    mVoiceWakeLock.release();
4477                }
4478            }
4479        }
4480    }
4481
4482    @Override
4483    public boolean startNextMatchingActivity(IBinder callingActivity,
4484            Intent intent, Bundle bOptions) {
4485        // Refuse possible leaked file descriptors
4486        if (intent != null && intent.hasFileDescriptors() == true) {
4487            throw new IllegalArgumentException("File descriptors passed in Intent");
4488        }
4489        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4490
4491        synchronized (this) {
4492            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4493            if (r == null) {
4494                ActivityOptions.abort(options);
4495                return false;
4496            }
4497            if (r.app == null || r.app.thread == null) {
4498                // The caller is not running...  d'oh!
4499                ActivityOptions.abort(options);
4500                return false;
4501            }
4502            intent = new Intent(intent);
4503            // The caller is not allowed to change the data.
4504            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4505            // And we are resetting to find the next component...
4506            intent.setComponent(null);
4507
4508            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4509
4510            ActivityInfo aInfo = null;
4511            try {
4512                List<ResolveInfo> resolves =
4513                    AppGlobals.getPackageManager().queryIntentActivities(
4514                            intent, r.resolvedType,
4515                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4516                            UserHandle.getCallingUserId()).getList();
4517
4518                // Look for the original activity in the list...
4519                final int N = resolves != null ? resolves.size() : 0;
4520                for (int i=0; i<N; i++) {
4521                    ResolveInfo rInfo = resolves.get(i);
4522                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4523                            && rInfo.activityInfo.name.equals(r.info.name)) {
4524                        // We found the current one...  the next matching is
4525                        // after it.
4526                        i++;
4527                        if (i<N) {
4528                            aInfo = resolves.get(i).activityInfo;
4529                        }
4530                        if (debug) {
4531                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4532                                    + "/" + r.info.name);
4533                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4534                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4535                        }
4536                        break;
4537                    }
4538                }
4539            } catch (RemoteException e) {
4540            }
4541
4542            if (aInfo == null) {
4543                // Nobody who is next!
4544                ActivityOptions.abort(options);
4545                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4546                return false;
4547            }
4548
4549            intent.setComponent(new ComponentName(
4550                    aInfo.applicationInfo.packageName, aInfo.name));
4551            intent.setFlags(intent.getFlags()&~(
4552                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4553                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4554                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4555                    Intent.FLAG_ACTIVITY_NEW_TASK));
4556
4557            // Okay now we need to start the new activity, replacing the
4558            // currently running activity.  This is a little tricky because
4559            // we want to start the new one as if the current one is finished,
4560            // but not finish the current one first so that there is no flicker.
4561            // And thus...
4562            final boolean wasFinishing = r.finishing;
4563            r.finishing = true;
4564
4565            // Propagate reply information over to the new activity.
4566            final ActivityRecord resultTo = r.resultTo;
4567            final String resultWho = r.resultWho;
4568            final int requestCode = r.requestCode;
4569            r.resultTo = null;
4570            if (resultTo != null) {
4571                resultTo.removeResultsLocked(r, resultWho, requestCode);
4572            }
4573
4574            final long origId = Binder.clearCallingIdentity();
4575            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4576                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4577                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4578                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4579                    false, false, null, null, null);
4580            Binder.restoreCallingIdentity(origId);
4581
4582            r.finishing = wasFinishing;
4583            if (res != ActivityManager.START_SUCCESS) {
4584                return false;
4585            }
4586            return true;
4587        }
4588    }
4589
4590    @Override
4591    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4592        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4593            String msg = "Permission Denial: startActivityFromRecents called without " +
4594                    START_TASKS_FROM_RECENTS;
4595            Slog.w(TAG, msg);
4596            throw new SecurityException(msg);
4597        }
4598        final long origId = Binder.clearCallingIdentity();
4599        try {
4600            synchronized (this) {
4601                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4602            }
4603        } finally {
4604            Binder.restoreCallingIdentity(origId);
4605        }
4606    }
4607
4608    final int startActivityInPackage(int uid, String callingPackage,
4609            Intent intent, String resolvedType, IBinder resultTo,
4610            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4611            IActivityContainer container, TaskRecord inTask) {
4612
4613        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4614                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4615
4616        // TODO: Switch to user app stacks here.
4617        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4618                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4619                null, null, null, bOptions, false, userId, container, inTask);
4620        return ret;
4621    }
4622
4623    @Override
4624    public final int startActivities(IApplicationThread caller, String callingPackage,
4625            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4626            int userId) {
4627        enforceNotIsolatedCaller("startActivities");
4628        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4629                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4630        // TODO: Switch to user app stacks here.
4631        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4632                resolvedTypes, resultTo, bOptions, userId);
4633        return ret;
4634    }
4635
4636    final int startActivitiesInPackage(int uid, String callingPackage,
4637            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4638            Bundle bOptions, int userId) {
4639
4640        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4641                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4642        // TODO: Switch to user app stacks here.
4643        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4644                resultTo, bOptions, userId);
4645        return ret;
4646    }
4647
4648    @Override
4649    public void reportActivityFullyDrawn(IBinder token) {
4650        synchronized (this) {
4651            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4652            if (r == null) {
4653                return;
4654            }
4655            r.reportFullyDrawnLocked();
4656        }
4657    }
4658
4659    @Override
4660    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4661        synchronized (this) {
4662            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4663            if (r == null) {
4664                return;
4665            }
4666            final long origId = Binder.clearCallingIdentity();
4667            try {
4668                r.setRequestedOrientation(requestedOrientation);
4669            } finally {
4670                Binder.restoreCallingIdentity(origId);
4671            }
4672        }
4673    }
4674
4675    @Override
4676    public int getRequestedOrientation(IBinder token) {
4677        synchronized (this) {
4678            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4679            if (r == null) {
4680                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4681            }
4682            return mWindowManager.getAppOrientation(r.appToken);
4683        }
4684    }
4685
4686    @Override
4687    public final void requestActivityRelaunch(IBinder token) {
4688        synchronized(this) {
4689            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4690            if (r == null) {
4691                return;
4692            }
4693            final long origId = Binder.clearCallingIdentity();
4694            try {
4695                r.forceNewConfig = true;
4696                r.ensureActivityConfigurationLocked(0 /* globalChanges */,
4697                        false /* preserveWindow */);
4698            } finally {
4699                Binder.restoreCallingIdentity(origId);
4700            }
4701        }
4702    }
4703
4704    /**
4705     * This is the internal entry point for handling Activity.finish().
4706     *
4707     * @param token The Binder token referencing the Activity we want to finish.
4708     * @param resultCode Result code, if any, from this Activity.
4709     * @param resultData Result data (Intent), if any, from this Activity.
4710     * @param finishTask Whether to finish the task associated with this Activity.
4711     *
4712     * @return Returns true if the activity successfully finished, or false if it is still running.
4713     */
4714    @Override
4715    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4716            int finishTask) {
4717        // Refuse possible leaked file descriptors
4718        if (resultData != null && resultData.hasFileDescriptors() == true) {
4719            throw new IllegalArgumentException("File descriptors passed in Intent");
4720        }
4721
4722        synchronized(this) {
4723            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4724            if (r == null) {
4725                return true;
4726            }
4727            // Keep track of the root activity of the task before we finish it
4728            TaskRecord tr = r.task;
4729            ActivityRecord rootR = tr.getRootActivity();
4730            if (rootR == null) {
4731                Slog.w(TAG, "Finishing task with all activities already finished");
4732            }
4733            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4734            // finish.
4735            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4736                    mStackSupervisor.isLastLockedTask(tr)) {
4737                Slog.i(TAG, "Not finishing task in lock task mode");
4738                mStackSupervisor.showLockTaskToast();
4739                return false;
4740            }
4741            if (mController != null) {
4742                // Find the first activity that is not finishing.
4743                ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
4744                if (next != null) {
4745                    // ask watcher if this is allowed
4746                    boolean resumeOK = true;
4747                    try {
4748                        resumeOK = mController.activityResuming(next.packageName);
4749                    } catch (RemoteException e) {
4750                        mController = null;
4751                        Watchdog.getInstance().setActivityController(null);
4752                    }
4753
4754                    if (!resumeOK) {
4755                        Slog.i(TAG, "Not finishing activity because controller resumed");
4756                        return false;
4757                    }
4758                }
4759            }
4760            final long origId = Binder.clearCallingIdentity();
4761            try {
4762                boolean res;
4763                final boolean finishWithRootActivity =
4764                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4765                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4766                        || (finishWithRootActivity && r == rootR)) {
4767                    // If requested, remove the task that is associated to this activity only if it
4768                    // was the root activity in the task. The result code and data is ignored
4769                    // because we don't support returning them across task boundaries. Also, to
4770                    // keep backwards compatibility we remove the task from recents when finishing
4771                    // task with root activity.
4772                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4773                    if (!res) {
4774                        Slog.i(TAG, "Removing task failed to finish activity");
4775                    }
4776                } else {
4777                    res = tr.getStack().requestFinishActivityLocked(token, resultCode,
4778                            resultData, "app-request", true);
4779                    if (!res) {
4780                        Slog.i(TAG, "Failed to finish by app-request");
4781                    }
4782                }
4783                return res;
4784            } finally {
4785                Binder.restoreCallingIdentity(origId);
4786            }
4787        }
4788    }
4789
4790    @Override
4791    public final void finishHeavyWeightApp() {
4792        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4793                != PackageManager.PERMISSION_GRANTED) {
4794            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4795                    + Binder.getCallingPid()
4796                    + ", uid=" + Binder.getCallingUid()
4797                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4798            Slog.w(TAG, msg);
4799            throw new SecurityException(msg);
4800        }
4801
4802        synchronized(this) {
4803            if (mHeavyWeightProcess == null) {
4804                return;
4805            }
4806
4807            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4808            for (int i = 0; i < activities.size(); i++) {
4809                ActivityRecord r = activities.get(i);
4810                if (!r.finishing && r.isInStackLocked()) {
4811                    r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
4812                            null, "finish-heavy", true);
4813                }
4814            }
4815
4816            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4817                    mHeavyWeightProcess.userId, 0));
4818            mHeavyWeightProcess = null;
4819        }
4820    }
4821
4822    @Override
4823    public void crashApplication(int uid, int initialPid, String packageName,
4824            String message) {
4825        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4826                != PackageManager.PERMISSION_GRANTED) {
4827            String msg = "Permission Denial: crashApplication() from pid="
4828                    + Binder.getCallingPid()
4829                    + ", uid=" + Binder.getCallingUid()
4830                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4831            Slog.w(TAG, msg);
4832            throw new SecurityException(msg);
4833        }
4834
4835        synchronized(this) {
4836            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4837        }
4838    }
4839
4840    @Override
4841    public final void finishSubActivity(IBinder token, String resultWho,
4842            int requestCode) {
4843        synchronized(this) {
4844            final long origId = Binder.clearCallingIdentity();
4845            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4846            if (r != null) {
4847                r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
4848            }
4849            Binder.restoreCallingIdentity(origId);
4850        }
4851    }
4852
4853    @Override
4854    public boolean finishActivityAffinity(IBinder token) {
4855        synchronized(this) {
4856            final long origId = Binder.clearCallingIdentity();
4857            try {
4858                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4859                if (r == null) {
4860                    return false;
4861                }
4862
4863                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4864                // can finish.
4865                final TaskRecord task = r.task;
4866                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4867                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4868                    mStackSupervisor.showLockTaskToast();
4869                    return false;
4870                }
4871                return task.getStack().finishActivityAffinityLocked(r);
4872            } finally {
4873                Binder.restoreCallingIdentity(origId);
4874            }
4875        }
4876    }
4877
4878    @Override
4879    public void finishVoiceTask(IVoiceInteractionSession session) {
4880        synchronized (this) {
4881            final long origId = Binder.clearCallingIdentity();
4882            try {
4883                // TODO: VI Consider treating local voice interactions and voice tasks
4884                // differently here
4885                mStackSupervisor.finishVoiceTask(session);
4886            } finally {
4887                Binder.restoreCallingIdentity(origId);
4888            }
4889        }
4890
4891    }
4892
4893    @Override
4894    public boolean releaseActivityInstance(IBinder token) {
4895        synchronized(this) {
4896            final long origId = Binder.clearCallingIdentity();
4897            try {
4898                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4899                if (r == null) {
4900                    return false;
4901                }
4902                return r.getStack().safelyDestroyActivityLocked(r, "app-req");
4903            } finally {
4904                Binder.restoreCallingIdentity(origId);
4905            }
4906        }
4907    }
4908
4909    @Override
4910    public void releaseSomeActivities(IApplicationThread appInt) {
4911        synchronized(this) {
4912            final long origId = Binder.clearCallingIdentity();
4913            try {
4914                ProcessRecord app = getRecordForAppLocked(appInt);
4915                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4916            } finally {
4917                Binder.restoreCallingIdentity(origId);
4918            }
4919        }
4920    }
4921
4922    @Override
4923    public boolean willActivityBeVisible(IBinder token) {
4924        synchronized(this) {
4925            ActivityStack stack = ActivityRecord.getStackLocked(token);
4926            if (stack != null) {
4927                return stack.willActivityBeVisibleLocked(token);
4928            }
4929            return false;
4930        }
4931    }
4932
4933    @Override
4934    public void overridePendingTransition(IBinder token, String packageName,
4935            int enterAnim, int exitAnim) {
4936        synchronized(this) {
4937            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4938            if (self == null) {
4939                return;
4940            }
4941
4942            final long origId = Binder.clearCallingIdentity();
4943
4944            if (self.state == ActivityState.RESUMED
4945                    || self.state == ActivityState.PAUSING) {
4946                mWindowManager.overridePendingAppTransition(packageName,
4947                        enterAnim, exitAnim, null);
4948            }
4949
4950            Binder.restoreCallingIdentity(origId);
4951        }
4952    }
4953
4954    /**
4955     * Main function for removing an existing process from the activity manager
4956     * as a result of that process going away.  Clears out all connections
4957     * to the process.
4958     */
4959    private final void handleAppDiedLocked(ProcessRecord app,
4960            boolean restarting, boolean allowRestart) {
4961        int pid = app.pid;
4962        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
4963                false /*replacingPid*/);
4964        if (!kept && !restarting) {
4965            removeLruProcessLocked(app);
4966            if (pid > 0) {
4967                ProcessList.remove(pid);
4968            }
4969        }
4970
4971        if (mProfileProc == app) {
4972            clearProfilerLocked();
4973        }
4974
4975        // Remove this application's activities from active lists.
4976        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4977
4978        app.activities.clear();
4979
4980        if (app.instrumentationClass != null) {
4981            Slog.w(TAG, "Crash of app " + app.processName
4982                  + " running instrumentation " + app.instrumentationClass);
4983            Bundle info = new Bundle();
4984            info.putString("shortMsg", "Process crashed.");
4985            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4986        }
4987
4988        if (!restarting && hasVisibleActivities
4989                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
4990            // If there was nothing to resume, and we are not already restarting this process, but
4991            // there is a visible activity that is hosted by the process...  then make sure all
4992            // visible activities are running, taking care of restarting this process.
4993            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
4994        }
4995    }
4996
4997    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4998        IBinder threadBinder = thread.asBinder();
4999        // Find the application record.
5000        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5001            ProcessRecord rec = mLruProcesses.get(i);
5002            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5003                return i;
5004            }
5005        }
5006        return -1;
5007    }
5008
5009    final ProcessRecord getRecordForAppLocked(
5010            IApplicationThread thread) {
5011        if (thread == null) {
5012            return null;
5013        }
5014
5015        int appIndex = getLRURecordIndexForAppLocked(thread);
5016        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5017    }
5018
5019    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5020        // If there are no longer any background processes running,
5021        // and the app that died was not running instrumentation,
5022        // then tell everyone we are now low on memory.
5023        boolean haveBg = false;
5024        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5025            ProcessRecord rec = mLruProcesses.get(i);
5026            if (rec.thread != null
5027                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5028                haveBg = true;
5029                break;
5030            }
5031        }
5032
5033        if (!haveBg) {
5034            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5035            if (doReport) {
5036                long now = SystemClock.uptimeMillis();
5037                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5038                    doReport = false;
5039                } else {
5040                    mLastMemUsageReportTime = now;
5041                }
5042            }
5043            final ArrayList<ProcessMemInfo> memInfos
5044                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5045            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5046            long now = SystemClock.uptimeMillis();
5047            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5048                ProcessRecord rec = mLruProcesses.get(i);
5049                if (rec == dyingProc || rec.thread == null) {
5050                    continue;
5051                }
5052                if (doReport) {
5053                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5054                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5055                }
5056                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5057                    // The low memory report is overriding any current
5058                    // state for a GC request.  Make sure to do
5059                    // heavy/important/visible/foreground processes first.
5060                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5061                        rec.lastRequestedGc = 0;
5062                    } else {
5063                        rec.lastRequestedGc = rec.lastLowMemory;
5064                    }
5065                    rec.reportLowMemory = true;
5066                    rec.lastLowMemory = now;
5067                    mProcessesToGc.remove(rec);
5068                    addProcessToGcListLocked(rec);
5069                }
5070            }
5071            if (doReport) {
5072                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5073                mHandler.sendMessage(msg);
5074            }
5075            scheduleAppGcsLocked();
5076        }
5077    }
5078
5079    final void appDiedLocked(ProcessRecord app) {
5080       appDiedLocked(app, app.pid, app.thread, false);
5081    }
5082
5083    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5084            boolean fromBinderDied) {
5085        // First check if this ProcessRecord is actually active for the pid.
5086        synchronized (mPidsSelfLocked) {
5087            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5088            if (curProc != app) {
5089                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5090                return;
5091            }
5092        }
5093
5094        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5095        synchronized (stats) {
5096            stats.noteProcessDiedLocked(app.info.uid, pid);
5097        }
5098
5099        if (!app.killed) {
5100            if (!fromBinderDied) {
5101                Process.killProcessQuiet(pid);
5102            }
5103            killProcessGroup(app.uid, pid);
5104            app.killed = true;
5105        }
5106
5107        // Clean up already done if the process has been re-started.
5108        if (app.pid == pid && app.thread != null &&
5109                app.thread.asBinder() == thread.asBinder()) {
5110            boolean doLowMem = app.instrumentationClass == null;
5111            boolean doOomAdj = doLowMem;
5112            if (!app.killedByAm) {
5113                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5114                        + ") has died");
5115                mAllowLowerMemLevel = true;
5116            } else {
5117                // Note that we always want to do oom adj to update our state with the
5118                // new number of procs.
5119                mAllowLowerMemLevel = false;
5120                doLowMem = false;
5121            }
5122            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5123            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5124                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5125            handleAppDiedLocked(app, false, true);
5126
5127            if (doOomAdj) {
5128                updateOomAdjLocked();
5129            }
5130            if (doLowMem) {
5131                doLowMemReportIfNeededLocked(app);
5132            }
5133        } else if (app.pid != pid) {
5134            // A new process has already been started.
5135            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5136                    + ") has died and restarted (pid " + app.pid + ").");
5137            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5138        } else if (DEBUG_PROCESSES) {
5139            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5140                    + thread.asBinder());
5141        }
5142    }
5143
5144    /**
5145     * If a stack trace dump file is configured, dump process stack traces.
5146     * @param clearTraces causes the dump file to be erased prior to the new
5147     *    traces being written, if true; when false, the new traces will be
5148     *    appended to any existing file content.
5149     * @param firstPids of dalvik VM processes to dump stack traces for first
5150     * @param lastPids of dalvik VM processes to dump stack traces for last
5151     * @param nativeProcs optional list of native process names to dump stack crawls
5152     * @return file containing stack traces, or null if no dump file is configured
5153     */
5154    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5155            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5156        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5157        if (tracesPath == null || tracesPath.length() == 0) {
5158            return null;
5159        }
5160
5161        File tracesFile = new File(tracesPath);
5162        try {
5163            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5164            tracesFile.createNewFile();
5165            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5166        } catch (IOException e) {
5167            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5168            return null;
5169        }
5170
5171        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5172        return tracesFile;
5173    }
5174
5175    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5176            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5177        // Use a FileObserver to detect when traces finish writing.
5178        // The order of traces is considered important to maintain for legibility.
5179        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5180            @Override
5181            public synchronized void onEvent(int event, String path) { notify(); }
5182        };
5183
5184        try {
5185            observer.startWatching();
5186
5187            // First collect all of the stacks of the most important pids.
5188            if (firstPids != null) {
5189                try {
5190                    int num = firstPids.size();
5191                    for (int i = 0; i < num; i++) {
5192                        synchronized (observer) {
5193                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5194                                    + firstPids.get(i));
5195                            final long sime = SystemClock.elapsedRealtime();
5196                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5197                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5198                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5199                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5200                        }
5201                    }
5202                } catch (InterruptedException e) {
5203                    Slog.wtf(TAG, e);
5204                }
5205            }
5206
5207            // Next collect the stacks of the native pids
5208            if (nativeProcs != null) {
5209                int[] pids = Process.getPidsForCommands(nativeProcs);
5210                if (pids != null) {
5211                    for (int pid : pids) {
5212                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5213                        final long sime = SystemClock.elapsedRealtime();
5214                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5215                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5216                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5217                    }
5218                }
5219            }
5220
5221            // Lastly, measure CPU usage.
5222            if (processCpuTracker != null) {
5223                processCpuTracker.init();
5224                System.gc();
5225                processCpuTracker.update();
5226                try {
5227                    synchronized (processCpuTracker) {
5228                        processCpuTracker.wait(500); // measure over 1/2 second.
5229                    }
5230                } catch (InterruptedException e) {
5231                }
5232                processCpuTracker.update();
5233
5234                // We'll take the stack crawls of just the top apps using CPU.
5235                final int N = processCpuTracker.countWorkingStats();
5236                int numProcs = 0;
5237                for (int i=0; i<N && numProcs<5; i++) {
5238                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5239                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5240                        numProcs++;
5241                        try {
5242                            synchronized (observer) {
5243                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5244                                        + stats.pid);
5245                                final long stime = SystemClock.elapsedRealtime();
5246                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5247                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5248                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5249                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5250                            }
5251                        } catch (InterruptedException e) {
5252                            Slog.wtf(TAG, e);
5253                        }
5254                    } else if (DEBUG_ANR) {
5255                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5256                                + stats.pid);
5257                    }
5258                }
5259            }
5260        } finally {
5261            observer.stopWatching();
5262        }
5263    }
5264
5265    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5266        if (true || IS_USER_BUILD) {
5267            return;
5268        }
5269        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5270        if (tracesPath == null || tracesPath.length() == 0) {
5271            return;
5272        }
5273
5274        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5275        StrictMode.allowThreadDiskWrites();
5276        try {
5277            final File tracesFile = new File(tracesPath);
5278            final File tracesDir = tracesFile.getParentFile();
5279            final File tracesTmp = new File(tracesDir, "__tmp__");
5280            try {
5281                if (tracesFile.exists()) {
5282                    tracesTmp.delete();
5283                    tracesFile.renameTo(tracesTmp);
5284                }
5285                StringBuilder sb = new StringBuilder();
5286                Time tobj = new Time();
5287                tobj.set(System.currentTimeMillis());
5288                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5289                sb.append(": ");
5290                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5291                sb.append(" since ");
5292                sb.append(msg);
5293                FileOutputStream fos = new FileOutputStream(tracesFile);
5294                fos.write(sb.toString().getBytes());
5295                if (app == null) {
5296                    fos.write("\n*** No application process!".getBytes());
5297                }
5298                fos.close();
5299                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5300            } catch (IOException e) {
5301                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5302                return;
5303            }
5304
5305            if (app != null) {
5306                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5307                firstPids.add(app.pid);
5308                dumpStackTraces(tracesPath, firstPids, null, null, null);
5309            }
5310
5311            File lastTracesFile = null;
5312            File curTracesFile = null;
5313            for (int i=9; i>=0; i--) {
5314                String name = String.format(Locale.US, "slow%02d.txt", i);
5315                curTracesFile = new File(tracesDir, name);
5316                if (curTracesFile.exists()) {
5317                    if (lastTracesFile != null) {
5318                        curTracesFile.renameTo(lastTracesFile);
5319                    } else {
5320                        curTracesFile.delete();
5321                    }
5322                }
5323                lastTracesFile = curTracesFile;
5324            }
5325            tracesFile.renameTo(curTracesFile);
5326            if (tracesTmp.exists()) {
5327                tracesTmp.renameTo(tracesFile);
5328            }
5329        } finally {
5330            StrictMode.setThreadPolicy(oldPolicy);
5331        }
5332    }
5333
5334    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5335        if (!mLaunchWarningShown) {
5336            mLaunchWarningShown = true;
5337            mUiHandler.post(new Runnable() {
5338                @Override
5339                public void run() {
5340                    synchronized (ActivityManagerService.this) {
5341                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5342                        d.show();
5343                        mUiHandler.postDelayed(new Runnable() {
5344                            @Override
5345                            public void run() {
5346                                synchronized (ActivityManagerService.this) {
5347                                    d.dismiss();
5348                                    mLaunchWarningShown = false;
5349                                }
5350                            }
5351                        }, 4000);
5352                    }
5353                }
5354            });
5355        }
5356    }
5357
5358    @Override
5359    public boolean clearApplicationUserData(final String packageName,
5360            final IPackageDataObserver observer, int userId) {
5361        enforceNotIsolatedCaller("clearApplicationUserData");
5362        int uid = Binder.getCallingUid();
5363        int pid = Binder.getCallingPid();
5364        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5365                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5366
5367
5368        long callingId = Binder.clearCallingIdentity();
5369        try {
5370            IPackageManager pm = AppGlobals.getPackageManager();
5371            int pkgUid = -1;
5372            synchronized(this) {
5373                if (getPackageManagerInternalLocked().isPackageDataProtected(
5374                        userId, packageName)) {
5375                    throw new SecurityException(
5376                            "Cannot clear data for a protected package: " + packageName);
5377                }
5378
5379                try {
5380                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5381                } catch (RemoteException e) {
5382                }
5383                if (pkgUid == -1) {
5384                    Slog.w(TAG, "Invalid packageName: " + packageName);
5385                    if (observer != null) {
5386                        try {
5387                            observer.onRemoveCompleted(packageName, false);
5388                        } catch (RemoteException e) {
5389                            Slog.i(TAG, "Observer no longer exists.");
5390                        }
5391                    }
5392                    return false;
5393                }
5394                if (uid == pkgUid || checkComponentPermission(
5395                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5396                        pid, uid, -1, true)
5397                        == PackageManager.PERMISSION_GRANTED) {
5398                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5399                } else {
5400                    throw new SecurityException("PID " + pid + " does not have permission "
5401                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5402                                    + " of package " + packageName);
5403                }
5404
5405                // Remove all tasks match the cleared application package and user
5406                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5407                    final TaskRecord tr = mRecentTasks.get(i);
5408                    final String taskPackageName =
5409                            tr.getBaseIntent().getComponent().getPackageName();
5410                    if (tr.userId != userId) continue;
5411                    if (!taskPackageName.equals(packageName)) continue;
5412                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5413                }
5414            }
5415
5416            final int pkgUidF = pkgUid;
5417            final int userIdF = userId;
5418            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5419                @Override
5420                public void onRemoveCompleted(String packageName, boolean succeeded)
5421                        throws RemoteException {
5422                    synchronized (ActivityManagerService.this) {
5423                        finishForceStopPackageLocked(packageName, pkgUidF);
5424                    }
5425
5426                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5427                            Uri.fromParts("package", packageName, null));
5428                    intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5429                    intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5430                    broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5431                            null, null, 0, null, null, null, null, false, false, userIdF);
5432
5433                    if (observer != null) {
5434                        observer.onRemoveCompleted(packageName, succeeded);
5435                    }
5436                }
5437            };
5438
5439            try {
5440                // Clear application user data
5441                pm.clearApplicationUserData(packageName, localObserver, userId);
5442
5443                synchronized(this) {
5444                    // Remove all permissions granted from/to this package
5445                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5446                }
5447
5448                // Remove all zen rules created by this package; revoke it's zen access.
5449                INotificationManager inm = NotificationManager.getService();
5450                inm.removeAutomaticZenRules(packageName);
5451                inm.setNotificationPolicyAccessGranted(packageName, false);
5452
5453            } catch (RemoteException e) {
5454            }
5455        } finally {
5456            Binder.restoreCallingIdentity(callingId);
5457        }
5458        return true;
5459    }
5460
5461    @Override
5462    public void killBackgroundProcesses(final String packageName, int userId) {
5463        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5464                != PackageManager.PERMISSION_GRANTED &&
5465                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5466                        != PackageManager.PERMISSION_GRANTED) {
5467            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5468                    + Binder.getCallingPid()
5469                    + ", uid=" + Binder.getCallingUid()
5470                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5471            Slog.w(TAG, msg);
5472            throw new SecurityException(msg);
5473        }
5474
5475        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5476                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5477        long callingId = Binder.clearCallingIdentity();
5478        try {
5479            IPackageManager pm = AppGlobals.getPackageManager();
5480            synchronized(this) {
5481                int appId = -1;
5482                try {
5483                    appId = UserHandle.getAppId(
5484                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5485                } catch (RemoteException e) {
5486                }
5487                if (appId == -1) {
5488                    Slog.w(TAG, "Invalid packageName: " + packageName);
5489                    return;
5490                }
5491                killPackageProcessesLocked(packageName, appId, userId,
5492                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5493            }
5494        } finally {
5495            Binder.restoreCallingIdentity(callingId);
5496        }
5497    }
5498
5499    @Override
5500    public void killAllBackgroundProcesses() {
5501        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5502                != PackageManager.PERMISSION_GRANTED) {
5503            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5504                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5505                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5506            Slog.w(TAG, msg);
5507            throw new SecurityException(msg);
5508        }
5509
5510        final long callingId = Binder.clearCallingIdentity();
5511        try {
5512            synchronized (this) {
5513                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5514                final int NP = mProcessNames.getMap().size();
5515                for (int ip = 0; ip < NP; ip++) {
5516                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5517                    final int NA = apps.size();
5518                    for (int ia = 0; ia < NA; ia++) {
5519                        final ProcessRecord app = apps.valueAt(ia);
5520                        if (app.persistent) {
5521                            // We don't kill persistent processes.
5522                            continue;
5523                        }
5524                        if (app.removed) {
5525                            procs.add(app);
5526                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5527                            app.removed = true;
5528                            procs.add(app);
5529                        }
5530                    }
5531                }
5532
5533                final int N = procs.size();
5534                for (int i = 0; i < N; i++) {
5535                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5536                }
5537
5538                mAllowLowerMemLevel = true;
5539
5540                updateOomAdjLocked();
5541                doLowMemReportIfNeededLocked(null);
5542            }
5543        } finally {
5544            Binder.restoreCallingIdentity(callingId);
5545        }
5546    }
5547
5548    /**
5549     * Kills all background processes, except those matching any of the
5550     * specified properties.
5551     *
5552     * @param minTargetSdk the target SDK version at or above which to preserve
5553     *                     processes, or {@code -1} to ignore the target SDK
5554     * @param maxProcState the process state at or below which to preserve
5555     *                     processes, or {@code -1} to ignore the process state
5556     */
5557    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5558        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5559                != PackageManager.PERMISSION_GRANTED) {
5560            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5561                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5562                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5563            Slog.w(TAG, msg);
5564            throw new SecurityException(msg);
5565        }
5566
5567        final long callingId = Binder.clearCallingIdentity();
5568        try {
5569            synchronized (this) {
5570                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5571                final int NP = mProcessNames.getMap().size();
5572                for (int ip = 0; ip < NP; ip++) {
5573                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5574                    final int NA = apps.size();
5575                    for (int ia = 0; ia < NA; ia++) {
5576                        final ProcessRecord app = apps.valueAt(ia);
5577                        if (app.removed) {
5578                            procs.add(app);
5579                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5580                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5581                            app.removed = true;
5582                            procs.add(app);
5583                        }
5584                    }
5585                }
5586
5587                final int N = procs.size();
5588                for (int i = 0; i < N; i++) {
5589                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5590                }
5591            }
5592        } finally {
5593            Binder.restoreCallingIdentity(callingId);
5594        }
5595    }
5596
5597    @Override
5598    public void forceStopPackage(final String packageName, int userId) {
5599        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5600                != PackageManager.PERMISSION_GRANTED) {
5601            String msg = "Permission Denial: forceStopPackage() from pid="
5602                    + Binder.getCallingPid()
5603                    + ", uid=" + Binder.getCallingUid()
5604                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5605            Slog.w(TAG, msg);
5606            throw new SecurityException(msg);
5607        }
5608        final int callingPid = Binder.getCallingPid();
5609        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5610                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5611        long callingId = Binder.clearCallingIdentity();
5612        try {
5613            IPackageManager pm = AppGlobals.getPackageManager();
5614            synchronized(this) {
5615                int[] users = userId == UserHandle.USER_ALL
5616                        ? mUserController.getUsers() : new int[] { userId };
5617                for (int user : users) {
5618                    int pkgUid = -1;
5619                    try {
5620                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5621                                user);
5622                    } catch (RemoteException e) {
5623                    }
5624                    if (pkgUid == -1) {
5625                        Slog.w(TAG, "Invalid packageName: " + packageName);
5626                        continue;
5627                    }
5628                    try {
5629                        pm.setPackageStoppedState(packageName, true, user);
5630                    } catch (RemoteException e) {
5631                    } catch (IllegalArgumentException e) {
5632                        Slog.w(TAG, "Failed trying to unstop package "
5633                                + packageName + ": " + e);
5634                    }
5635                    if (mUserController.isUserRunningLocked(user, 0)) {
5636                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5637                        finishForceStopPackageLocked(packageName, pkgUid);
5638                    }
5639                }
5640            }
5641        } finally {
5642            Binder.restoreCallingIdentity(callingId);
5643        }
5644    }
5645
5646    @Override
5647    public void addPackageDependency(String packageName) {
5648        synchronized (this) {
5649            int callingPid = Binder.getCallingPid();
5650            if (callingPid == Process.myPid()) {
5651                //  Yeah, um, no.
5652                return;
5653            }
5654            ProcessRecord proc;
5655            synchronized (mPidsSelfLocked) {
5656                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5657            }
5658            if (proc != null) {
5659                if (proc.pkgDeps == null) {
5660                    proc.pkgDeps = new ArraySet<String>(1);
5661                }
5662                proc.pkgDeps.add(packageName);
5663            }
5664        }
5665    }
5666
5667    /*
5668     * The pkg name and app id have to be specified.
5669     */
5670    @Override
5671    public void killApplication(String pkg, int appId, int userId, String reason) {
5672        if (pkg == null) {
5673            return;
5674        }
5675        // Make sure the uid is valid.
5676        if (appId < 0) {
5677            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5678            return;
5679        }
5680        int callerUid = Binder.getCallingUid();
5681        // Only the system server can kill an application
5682        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5683            // Post an aysnc message to kill the application
5684            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5685            msg.arg1 = appId;
5686            msg.arg2 = userId;
5687            Bundle bundle = new Bundle();
5688            bundle.putString("pkg", pkg);
5689            bundle.putString("reason", reason);
5690            msg.obj = bundle;
5691            mHandler.sendMessage(msg);
5692        } else {
5693            throw new SecurityException(callerUid + " cannot kill pkg: " +
5694                    pkg);
5695        }
5696    }
5697
5698    @Override
5699    public void closeSystemDialogs(String reason) {
5700        enforceNotIsolatedCaller("closeSystemDialogs");
5701
5702        final int pid = Binder.getCallingPid();
5703        final int uid = Binder.getCallingUid();
5704        final long origId = Binder.clearCallingIdentity();
5705        try {
5706            synchronized (this) {
5707                // Only allow this from foreground processes, so that background
5708                // applications can't abuse it to prevent system UI from being shown.
5709                if (uid >= Process.FIRST_APPLICATION_UID) {
5710                    ProcessRecord proc;
5711                    synchronized (mPidsSelfLocked) {
5712                        proc = mPidsSelfLocked.get(pid);
5713                    }
5714                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5715                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5716                                + " from background process " + proc);
5717                        return;
5718                    }
5719                }
5720                closeSystemDialogsLocked(reason);
5721            }
5722        } finally {
5723            Binder.restoreCallingIdentity(origId);
5724        }
5725    }
5726
5727    void closeSystemDialogsLocked(String reason) {
5728        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5729        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5730                | Intent.FLAG_RECEIVER_FOREGROUND);
5731        if (reason != null) {
5732            intent.putExtra("reason", reason);
5733        }
5734        mWindowManager.closeSystemDialogs(reason);
5735
5736        mStackSupervisor.closeSystemDialogsLocked();
5737
5738        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5739                AppOpsManager.OP_NONE, null, false, false,
5740                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5741    }
5742
5743    @Override
5744    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5745        enforceNotIsolatedCaller("getProcessMemoryInfo");
5746        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5747        for (int i=pids.length-1; i>=0; i--) {
5748            ProcessRecord proc;
5749            int oomAdj;
5750            synchronized (this) {
5751                synchronized (mPidsSelfLocked) {
5752                    proc = mPidsSelfLocked.get(pids[i]);
5753                    oomAdj = proc != null ? proc.setAdj : 0;
5754                }
5755            }
5756            infos[i] = new Debug.MemoryInfo();
5757            Debug.getMemoryInfo(pids[i], infos[i]);
5758            if (proc != null) {
5759                synchronized (this) {
5760                    if (proc.thread != null && proc.setAdj == oomAdj) {
5761                        // Record this for posterity if the process has been stable.
5762                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5763                                infos[i].getTotalUss(), false, proc.pkgList);
5764                    }
5765                }
5766            }
5767        }
5768        return infos;
5769    }
5770
5771    @Override
5772    public long[] getProcessPss(int[] pids) {
5773        enforceNotIsolatedCaller("getProcessPss");
5774        long[] pss = new long[pids.length];
5775        for (int i=pids.length-1; i>=0; i--) {
5776            ProcessRecord proc;
5777            int oomAdj;
5778            synchronized (this) {
5779                synchronized (mPidsSelfLocked) {
5780                    proc = mPidsSelfLocked.get(pids[i]);
5781                    oomAdj = proc != null ? proc.setAdj : 0;
5782                }
5783            }
5784            long[] tmpUss = new long[1];
5785            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5786            if (proc != null) {
5787                synchronized (this) {
5788                    if (proc.thread != null && proc.setAdj == oomAdj) {
5789                        // Record this for posterity if the process has been stable.
5790                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5791                    }
5792                }
5793            }
5794        }
5795        return pss;
5796    }
5797
5798    @Override
5799    public void killApplicationProcess(String processName, int uid) {
5800        if (processName == null) {
5801            return;
5802        }
5803
5804        int callerUid = Binder.getCallingUid();
5805        // Only the system server can kill an application
5806        if (callerUid == Process.SYSTEM_UID) {
5807            synchronized (this) {
5808                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5809                if (app != null && app.thread != null) {
5810                    try {
5811                        app.thread.scheduleSuicide();
5812                    } catch (RemoteException e) {
5813                        // If the other end already died, then our work here is done.
5814                    }
5815                } else {
5816                    Slog.w(TAG, "Process/uid not found attempting kill of "
5817                            + processName + " / " + uid);
5818                }
5819            }
5820        } else {
5821            throw new SecurityException(callerUid + " cannot kill app process: " +
5822                    processName);
5823        }
5824    }
5825
5826    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5827        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5828                false, true, false, false, UserHandle.getUserId(uid), reason);
5829    }
5830
5831    private void finishForceStopPackageLocked(final String packageName, int uid) {
5832        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5833                Uri.fromParts("package", packageName, null));
5834        if (!mProcessesReady) {
5835            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5836                    | Intent.FLAG_RECEIVER_FOREGROUND);
5837        }
5838        intent.putExtra(Intent.EXTRA_UID, uid);
5839        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5840        broadcastIntentLocked(null, null, intent,
5841                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5842                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5843    }
5844
5845
5846    private final boolean killPackageProcessesLocked(String packageName, int appId,
5847            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5848            boolean doit, boolean evenPersistent, String reason) {
5849        ArrayList<ProcessRecord> procs = new ArrayList<>();
5850
5851        // Remove all processes this package may have touched: all with the
5852        // same UID (except for the system or root user), and all whose name
5853        // matches the package name.
5854        final int NP = mProcessNames.getMap().size();
5855        for (int ip=0; ip<NP; ip++) {
5856            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5857            final int NA = apps.size();
5858            for (int ia=0; ia<NA; ia++) {
5859                ProcessRecord app = apps.valueAt(ia);
5860                if (app.persistent && !evenPersistent) {
5861                    // we don't kill persistent processes
5862                    continue;
5863                }
5864                if (app.removed) {
5865                    if (doit) {
5866                        procs.add(app);
5867                    }
5868                    continue;
5869                }
5870
5871                // Skip process if it doesn't meet our oom adj requirement.
5872                if (app.setAdj < minOomAdj) {
5873                    continue;
5874                }
5875
5876                // If no package is specified, we call all processes under the
5877                // give user id.
5878                if (packageName == null) {
5879                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5880                        continue;
5881                    }
5882                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5883                        continue;
5884                    }
5885                // Package has been specified, we want to hit all processes
5886                // that match it.  We need to qualify this by the processes
5887                // that are running under the specified app and user ID.
5888                } else {
5889                    final boolean isDep = app.pkgDeps != null
5890                            && app.pkgDeps.contains(packageName);
5891                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5892                        continue;
5893                    }
5894                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5895                        continue;
5896                    }
5897                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5898                        continue;
5899                    }
5900                }
5901
5902                // Process has passed all conditions, kill it!
5903                if (!doit) {
5904                    return true;
5905                }
5906                app.removed = true;
5907                procs.add(app);
5908            }
5909        }
5910
5911        int N = procs.size();
5912        for (int i=0; i<N; i++) {
5913            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5914        }
5915        updateOomAdjLocked();
5916        return N > 0;
5917    }
5918
5919    private void cleanupDisabledPackageComponentsLocked(
5920            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5921
5922        Set<String> disabledClasses = null;
5923        boolean packageDisabled = false;
5924        IPackageManager pm = AppGlobals.getPackageManager();
5925
5926        if (changedClasses == null) {
5927            // Nothing changed...
5928            return;
5929        }
5930
5931        // Determine enable/disable state of the package and its components.
5932        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5933        for (int i = changedClasses.length - 1; i >= 0; i--) {
5934            final String changedClass = changedClasses[i];
5935
5936            if (changedClass.equals(packageName)) {
5937                try {
5938                    // Entire package setting changed
5939                    enabled = pm.getApplicationEnabledSetting(packageName,
5940                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5941                } catch (Exception e) {
5942                    // No such package/component; probably racing with uninstall.  In any
5943                    // event it means we have nothing further to do here.
5944                    return;
5945                }
5946                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5947                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5948                if (packageDisabled) {
5949                    // Entire package is disabled.
5950                    // No need to continue to check component states.
5951                    disabledClasses = null;
5952                    break;
5953                }
5954            } else {
5955                try {
5956                    enabled = pm.getComponentEnabledSetting(
5957                            new ComponentName(packageName, changedClass),
5958                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5959                } catch (Exception e) {
5960                    // As above, probably racing with uninstall.
5961                    return;
5962                }
5963                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5964                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5965                    if (disabledClasses == null) {
5966                        disabledClasses = new ArraySet<>(changedClasses.length);
5967                    }
5968                    disabledClasses.add(changedClass);
5969                }
5970            }
5971        }
5972
5973        if (!packageDisabled && disabledClasses == null) {
5974            // Nothing to do here...
5975            return;
5976        }
5977
5978        // Clean-up disabled activities.
5979        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5980                packageName, disabledClasses, true, false, userId) && mBooted) {
5981            mStackSupervisor.resumeFocusedStackTopActivityLocked();
5982            mStackSupervisor.scheduleIdleLocked();
5983        }
5984
5985        // Clean-up disabled tasks
5986        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5987
5988        // Clean-up disabled services.
5989        mServices.bringDownDisabledPackageServicesLocked(
5990                packageName, disabledClasses, userId, false, killProcess, true);
5991
5992        // Clean-up disabled providers.
5993        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5994        mProviderMap.collectPackageProvidersLocked(
5995                packageName, disabledClasses, true, false, userId, providers);
5996        for (int i = providers.size() - 1; i >= 0; i--) {
5997            removeDyingProviderLocked(null, providers.get(i), true);
5998        }
5999
6000        // Clean-up disabled broadcast receivers.
6001        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6002            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6003                    packageName, disabledClasses, userId, true);
6004        }
6005
6006    }
6007
6008    final boolean clearBroadcastQueueForUserLocked(int userId) {
6009        boolean didSomething = false;
6010        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6011            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6012                    null, null, userId, true);
6013        }
6014        return didSomething;
6015    }
6016
6017    final boolean forceStopPackageLocked(String packageName, int appId,
6018            boolean callerWillRestart, boolean purgeCache, boolean doit,
6019            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6020        int i;
6021
6022        if (userId == UserHandle.USER_ALL && packageName == null) {
6023            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6024        }
6025
6026        if (appId < 0 && packageName != null) {
6027            try {
6028                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6029                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6030            } catch (RemoteException e) {
6031            }
6032        }
6033
6034        if (doit) {
6035            if (packageName != null) {
6036                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6037                        + " user=" + userId + ": " + reason);
6038            } else {
6039                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6040            }
6041
6042            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6043        }
6044
6045        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6046                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6047                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6048
6049        didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName);
6050
6051        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6052                packageName, null, doit, evenPersistent, userId)) {
6053            if (!doit) {
6054                return true;
6055            }
6056            didSomething = true;
6057        }
6058
6059        if (mServices.bringDownDisabledPackageServicesLocked(
6060                packageName, null, userId, evenPersistent, true, doit)) {
6061            if (!doit) {
6062                return true;
6063            }
6064            didSomething = true;
6065        }
6066
6067        if (packageName == null) {
6068            // Remove all sticky broadcasts from this user.
6069            mStickyBroadcasts.remove(userId);
6070        }
6071
6072        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6073        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6074                userId, providers)) {
6075            if (!doit) {
6076                return true;
6077            }
6078            didSomething = true;
6079        }
6080        for (i = providers.size() - 1; i >= 0; i--) {
6081            removeDyingProviderLocked(null, providers.get(i), true);
6082        }
6083
6084        // Remove transient permissions granted from/to this package/user
6085        removeUriPermissionsForPackageLocked(packageName, userId, false);
6086
6087        if (doit) {
6088            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6089                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6090                        packageName, null, userId, doit);
6091            }
6092        }
6093
6094        if (packageName == null || uninstalling) {
6095            // Remove pending intents.  For now we only do this when force
6096            // stopping users, because we have some problems when doing this
6097            // for packages -- app widgets are not currently cleaned up for
6098            // such packages, so they can be left with bad pending intents.
6099            if (mIntentSenderRecords.size() > 0) {
6100                Iterator<WeakReference<PendingIntentRecord>> it
6101                        = mIntentSenderRecords.values().iterator();
6102                while (it.hasNext()) {
6103                    WeakReference<PendingIntentRecord> wpir = it.next();
6104                    if (wpir == null) {
6105                        it.remove();
6106                        continue;
6107                    }
6108                    PendingIntentRecord pir = wpir.get();
6109                    if (pir == null) {
6110                        it.remove();
6111                        continue;
6112                    }
6113                    if (packageName == null) {
6114                        // Stopping user, remove all objects for the user.
6115                        if (pir.key.userId != userId) {
6116                            // Not the same user, skip it.
6117                            continue;
6118                        }
6119                    } else {
6120                        if (UserHandle.getAppId(pir.uid) != appId) {
6121                            // Different app id, skip it.
6122                            continue;
6123                        }
6124                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6125                            // Different user, skip it.
6126                            continue;
6127                        }
6128                        if (!pir.key.packageName.equals(packageName)) {
6129                            // Different package, skip it.
6130                            continue;
6131                        }
6132                    }
6133                    if (!doit) {
6134                        return true;
6135                    }
6136                    didSomething = true;
6137                    it.remove();
6138                    pir.canceled = true;
6139                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6140                        pir.key.activity.pendingResults.remove(pir.ref);
6141                    }
6142                }
6143            }
6144        }
6145
6146        if (doit) {
6147            if (purgeCache && packageName != null) {
6148                AttributeCache ac = AttributeCache.instance();
6149                if (ac != null) {
6150                    ac.removePackage(packageName);
6151                }
6152            }
6153            if (mBooted) {
6154                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6155                mStackSupervisor.scheduleIdleLocked();
6156            }
6157        }
6158
6159        return didSomething;
6160    }
6161
6162    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6163        ProcessRecord old = mProcessNames.remove(name, uid);
6164        if (old != null) {
6165            old.uidRecord.numProcs--;
6166            if (old.uidRecord.numProcs == 0) {
6167                // No more processes using this uid, tell clients it is gone.
6168                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6169                        "No more processes in " + old.uidRecord);
6170                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6171                mActiveUids.remove(uid);
6172                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6173            }
6174            old.uidRecord = null;
6175        }
6176        mIsolatedProcesses.remove(uid);
6177        return old;
6178    }
6179
6180    private final void addProcessNameLocked(ProcessRecord proc) {
6181        // We shouldn't already have a process under this name, but just in case we
6182        // need to clean up whatever may be there now.
6183        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6184        if (old == proc && proc.persistent) {
6185            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6186            Slog.w(TAG, "Re-adding persistent process " + proc);
6187        } else if (old != null) {
6188            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6189        }
6190        UidRecord uidRec = mActiveUids.get(proc.uid);
6191        if (uidRec == null) {
6192            uidRec = new UidRecord(proc.uid);
6193            // This is the first appearance of the uid, report it now!
6194            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6195                    "Creating new process uid: " + uidRec);
6196            mActiveUids.put(proc.uid, uidRec);
6197            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6198            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6199        }
6200        proc.uidRecord = uidRec;
6201
6202        // Reset render thread tid if it was already set, so new process can set it again.
6203        proc.renderThreadTid = 0;
6204        uidRec.numProcs++;
6205        mProcessNames.put(proc.processName, proc.uid, proc);
6206        if (proc.isolated) {
6207            mIsolatedProcesses.put(proc.uid, proc);
6208        }
6209    }
6210
6211    boolean removeProcessLocked(ProcessRecord app,
6212            boolean callerWillRestart, boolean allowRestart, String reason) {
6213        final String name = app.processName;
6214        final int uid = app.uid;
6215        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6216            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6217
6218        ProcessRecord old = mProcessNames.get(name, uid);
6219        if (old != app) {
6220            // This process is no longer active, so nothing to do.
6221            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6222            return false;
6223        }
6224        removeProcessNameLocked(name, uid);
6225        if (mHeavyWeightProcess == app) {
6226            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6227                    mHeavyWeightProcess.userId, 0));
6228            mHeavyWeightProcess = null;
6229        }
6230        boolean needRestart = false;
6231        if (app.pid > 0 && app.pid != MY_PID) {
6232            int pid = app.pid;
6233            synchronized (mPidsSelfLocked) {
6234                mPidsSelfLocked.remove(pid);
6235                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6236            }
6237            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6238            if (app.isolated) {
6239                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6240            }
6241            boolean willRestart = false;
6242            if (app.persistent && !app.isolated) {
6243                if (!callerWillRestart) {
6244                    willRestart = true;
6245                } else {
6246                    needRestart = true;
6247                }
6248            }
6249            app.kill(reason, true);
6250            handleAppDiedLocked(app, willRestart, allowRestart);
6251            if (willRestart) {
6252                removeLruProcessLocked(app);
6253                addAppLocked(app.info, false, null /* ABI override */);
6254            }
6255        } else {
6256            mRemovedProcesses.add(app);
6257        }
6258
6259        return needRestart;
6260    }
6261
6262    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6263        cleanupAppInLaunchingProvidersLocked(app, true);
6264        removeProcessLocked(app, false, true, "timeout publishing content providers");
6265    }
6266
6267    private final void processStartTimedOutLocked(ProcessRecord app) {
6268        final int pid = app.pid;
6269        boolean gone = false;
6270        synchronized (mPidsSelfLocked) {
6271            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6272            if (knownApp != null && knownApp.thread == null) {
6273                mPidsSelfLocked.remove(pid);
6274                gone = true;
6275            }
6276        }
6277
6278        if (gone) {
6279            Slog.w(TAG, "Process " + app + " failed to attach");
6280            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6281                    pid, app.uid, app.processName);
6282            removeProcessNameLocked(app.processName, app.uid);
6283            if (mHeavyWeightProcess == app) {
6284                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6285                        mHeavyWeightProcess.userId, 0));
6286                mHeavyWeightProcess = null;
6287            }
6288            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6289            if (app.isolated) {
6290                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6291            }
6292            // Take care of any launching providers waiting for this process.
6293            cleanupAppInLaunchingProvidersLocked(app, true);
6294            // Take care of any services that are waiting for the process.
6295            mServices.processStartTimedOutLocked(app);
6296            app.kill("start timeout", true);
6297            removeLruProcessLocked(app);
6298            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6299                Slog.w(TAG, "Unattached app died before backup, skipping");
6300                try {
6301                    IBackupManager bm = IBackupManager.Stub.asInterface(
6302                            ServiceManager.getService(Context.BACKUP_SERVICE));
6303                    bm.agentDisconnected(app.info.packageName);
6304                } catch (RemoteException e) {
6305                    // Can't happen; the backup manager is local
6306                }
6307            }
6308            if (isPendingBroadcastProcessLocked(pid)) {
6309                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6310                skipPendingBroadcastLocked(pid);
6311            }
6312        } else {
6313            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6314        }
6315    }
6316
6317    private final boolean attachApplicationLocked(IApplicationThread thread,
6318            int pid) {
6319
6320        // Find the application record that is being attached...  either via
6321        // the pid if we are running in multiple processes, or just pull the
6322        // next app record if we are emulating process with anonymous threads.
6323        ProcessRecord app;
6324        if (pid != MY_PID && pid >= 0) {
6325            synchronized (mPidsSelfLocked) {
6326                app = mPidsSelfLocked.get(pid);
6327            }
6328        } else {
6329            app = null;
6330        }
6331
6332        if (app == null) {
6333            Slog.w(TAG, "No pending application record for pid " + pid
6334                    + " (IApplicationThread " + thread + "); dropping process");
6335            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6336            if (pid > 0 && pid != MY_PID) {
6337                Process.killProcessQuiet(pid);
6338                //TODO: killProcessGroup(app.info.uid, pid);
6339            } else {
6340                try {
6341                    thread.scheduleExit();
6342                } catch (Exception e) {
6343                    // Ignore exceptions.
6344                }
6345            }
6346            return false;
6347        }
6348
6349        // If this application record is still attached to a previous
6350        // process, clean it up now.
6351        if (app.thread != null) {
6352            handleAppDiedLocked(app, true, true);
6353        }
6354
6355        // Tell the process all about itself.
6356
6357        if (DEBUG_ALL) Slog.v(
6358                TAG, "Binding process pid " + pid + " to record " + app);
6359
6360        final String processName = app.processName;
6361        try {
6362            AppDeathRecipient adr = new AppDeathRecipient(
6363                    app, pid, thread);
6364            thread.asBinder().linkToDeath(adr, 0);
6365            app.deathRecipient = adr;
6366        } catch (RemoteException e) {
6367            app.resetPackageList(mProcessStats);
6368            startProcessLocked(app, "link fail", processName);
6369            return false;
6370        }
6371
6372        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6373
6374        app.makeActive(thread, mProcessStats);
6375        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6376        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6377        app.forcingToForeground = null;
6378        updateProcessForegroundLocked(app, false, false);
6379        app.hasShownUi = false;
6380        app.debugging = false;
6381        app.cached = false;
6382        app.killedByAm = false;
6383        app.killed = false;
6384
6385
6386        // We carefully use the same state that PackageManager uses for
6387        // filtering, since we use this flag to decide if we need to install
6388        // providers when user is unlocked later
6389        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6390
6391        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6392
6393        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6394        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6395
6396        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6397            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6398            msg.obj = app;
6399            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6400        }
6401
6402        if (!normalMode) {
6403            Slog.i(TAG, "Launching preboot mode app: " + app);
6404        }
6405
6406        if (DEBUG_ALL) Slog.v(
6407            TAG, "New app record " + app
6408            + " thread=" + thread.asBinder() + " pid=" + pid);
6409        try {
6410            int testMode = ApplicationThreadConstants.DEBUG_OFF;
6411            if (mDebugApp != null && mDebugApp.equals(processName)) {
6412                testMode = mWaitForDebugger
6413                    ? ApplicationThreadConstants.DEBUG_WAIT
6414                    : ApplicationThreadConstants.DEBUG_ON;
6415                app.debugging = true;
6416                if (mDebugTransient) {
6417                    mDebugApp = mOrigDebugApp;
6418                    mWaitForDebugger = mOrigWaitForDebugger;
6419                }
6420            }
6421            String profileFile = app.instrumentationProfileFile;
6422            ParcelFileDescriptor profileFd = null;
6423            int samplingInterval = 0;
6424            boolean profileAutoStop = false;
6425            if (mProfileApp != null && mProfileApp.equals(processName)) {
6426                mProfileProc = app;
6427                profileFile = mProfileFile;
6428                profileFd = mProfileFd;
6429                samplingInterval = mSamplingInterval;
6430                profileAutoStop = mAutoStopProfiler;
6431            }
6432            boolean enableTrackAllocation = false;
6433            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6434                enableTrackAllocation = true;
6435                mTrackAllocationApp = null;
6436            }
6437
6438            // If the app is being launched for restore or full backup, set it up specially
6439            boolean isRestrictedBackupMode = false;
6440            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6441                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6442                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6443                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6444                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6445            }
6446
6447            if (app.instrumentationClass != null) {
6448                notifyPackageUse(app.instrumentationClass.getPackageName(),
6449                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6450            }
6451            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6452                    + processName + " with config " + getGlobalConfiguration());
6453            ApplicationInfo appInfo = app.instrumentationInfo != null
6454                    ? app.instrumentationInfo : app.info;
6455            app.compat = compatibilityInfoForPackageLocked(appInfo);
6456            if (profileFd != null) {
6457                profileFd = profileFd.dup();
6458            }
6459            ProfilerInfo profilerInfo = profileFile == null ? null
6460                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6461
6462            // We deprecated Build.SERIAL and only apps that target pre NMR1
6463            // SDK can see it. Since access to the serial is now behind a
6464            // permission we push down the value.
6465            String buildSerial = Build.UNKNOWN;
6466            if (appInfo.targetSdkVersion <= Build.VERSION_CODES.N_MR1) {
6467                buildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
6468                        ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
6469                        .getSerial();
6470            }
6471
6472            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6473                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6474                    app.instrumentationUiAutomationConnection, testMode,
6475                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6476                    isRestrictedBackupMode || !normalMode, app.persistent,
6477                    new Configuration(getGlobalConfiguration()), app.compat,
6478                    getCommonServicesLocked(app.isolated),
6479                    mCoreSettingsObserver.getCoreSettingsLocked(),
6480                    buildSerial);
6481
6482            updateLruProcessLocked(app, false, null);
6483            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6484        } catch (Exception e) {
6485            // todo: Yikes!  What should we do?  For now we will try to
6486            // start another process, but that could easily get us in
6487            // an infinite loop of restarting processes...
6488            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6489
6490            app.resetPackageList(mProcessStats);
6491            app.unlinkDeathRecipient();
6492            startProcessLocked(app, "bind fail", processName);
6493            return false;
6494        }
6495
6496        // Remove this record from the list of starting applications.
6497        mPersistentStartingProcesses.remove(app);
6498        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6499                "Attach application locked removing on hold: " + app);
6500        mProcessesOnHold.remove(app);
6501
6502        boolean badApp = false;
6503        boolean didSomething = false;
6504
6505        // See if the top visible activity is waiting to run in this process...
6506        if (normalMode) {
6507            try {
6508                if (mStackSupervisor.attachApplicationLocked(app)) {
6509                    didSomething = true;
6510                }
6511            } catch (Exception e) {
6512                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6513                badApp = true;
6514            }
6515        }
6516
6517        // Find any services that should be running in this process...
6518        if (!badApp) {
6519            try {
6520                didSomething |= mServices.attachApplicationLocked(app, processName);
6521            } catch (Exception e) {
6522                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6523                badApp = true;
6524            }
6525        }
6526
6527        // Check if a next-broadcast receiver is in this process...
6528        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6529            try {
6530                didSomething |= sendPendingBroadcastsLocked(app);
6531            } catch (Exception e) {
6532                // If the app died trying to launch the receiver we declare it 'bad'
6533                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6534                badApp = true;
6535            }
6536        }
6537
6538        // Check whether the next backup agent is in this process...
6539        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6540            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6541                    "New app is backup target, launching agent for " + app);
6542            notifyPackageUse(mBackupTarget.appInfo.packageName,
6543                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6544            try {
6545                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6546                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6547                        mBackupTarget.backupMode);
6548            } catch (Exception e) {
6549                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6550                badApp = true;
6551            }
6552        }
6553
6554        if (badApp) {
6555            app.kill("error during init", true);
6556            handleAppDiedLocked(app, false, true);
6557            return false;
6558        }
6559
6560        if (!didSomething) {
6561            updateOomAdjLocked();
6562        }
6563
6564        return true;
6565    }
6566
6567    @Override
6568    public final void attachApplication(IApplicationThread thread) {
6569        synchronized (this) {
6570            int callingPid = Binder.getCallingPid();
6571            final long origId = Binder.clearCallingIdentity();
6572            attachApplicationLocked(thread, callingPid);
6573            Binder.restoreCallingIdentity(origId);
6574        }
6575    }
6576
6577    @Override
6578    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6579        final long origId = Binder.clearCallingIdentity();
6580        synchronized (this) {
6581            ActivityStack stack = ActivityRecord.getStackLocked(token);
6582            if (stack != null) {
6583                ActivityRecord r =
6584                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6585                if (stopProfiling) {
6586                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6587                        try {
6588                            mProfileFd.close();
6589                        } catch (IOException e) {
6590                        }
6591                        clearProfilerLocked();
6592                    }
6593                }
6594            }
6595        }
6596        Binder.restoreCallingIdentity(origId);
6597    }
6598
6599    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6600        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6601                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6602    }
6603
6604    void enableScreenAfterBoot() {
6605        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6606                SystemClock.uptimeMillis());
6607        mWindowManager.enableScreenAfterBoot();
6608
6609        synchronized (this) {
6610            updateEventDispatchingLocked();
6611        }
6612    }
6613
6614    @Override
6615    public void showBootMessage(final CharSequence msg, final boolean always) {
6616        if (Binder.getCallingUid() != Process.myUid()) {
6617            throw new SecurityException();
6618        }
6619        mWindowManager.showBootMessage(msg, always);
6620    }
6621
6622    @Override
6623    public void keyguardWaitingForActivityDrawn() {
6624        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6625        final long token = Binder.clearCallingIdentity();
6626        try {
6627            synchronized (this) {
6628                if (DEBUG_LOCKSCREEN) logLockScreen("");
6629                mWindowManager.keyguardWaitingForActivityDrawn();
6630                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6631                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6632                    updateSleepIfNeededLocked();
6633                }
6634            }
6635        } finally {
6636            Binder.restoreCallingIdentity(token);
6637        }
6638    }
6639
6640    @Override
6641    public void keyguardGoingAway(int flags) {
6642        enforceNotIsolatedCaller("keyguardGoingAway");
6643        final long token = Binder.clearCallingIdentity();
6644        try {
6645            synchronized (this) {
6646                if (DEBUG_LOCKSCREEN) logLockScreen("");
6647                mWindowManager.keyguardGoingAway(flags);
6648                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6649                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6650                    updateSleepIfNeededLocked();
6651
6652                    // Some stack visibility might change (e.g. docked stack)
6653                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6654                    applyVrModeIfNeededLocked(mStackSupervisor.getResumedActivityLocked(), true);
6655                }
6656            }
6657        } finally {
6658            Binder.restoreCallingIdentity(token);
6659        }
6660    }
6661
6662    final void finishBooting() {
6663        synchronized (this) {
6664            if (!mBootAnimationComplete) {
6665                mCallFinishBooting = true;
6666                return;
6667            }
6668            mCallFinishBooting = false;
6669        }
6670
6671        ArraySet<String> completedIsas = new ArraySet<String>();
6672        for (String abi : Build.SUPPORTED_ABIS) {
6673            Process.zygoteProcess.establishZygoteConnectionForAbi(abi);
6674            final String instructionSet = VMRuntime.getInstructionSet(abi);
6675            if (!completedIsas.contains(instructionSet)) {
6676                try {
6677                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6678                } catch (InstallerException e) {
6679                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6680                            e.getMessage() +")");
6681                }
6682                completedIsas.add(instructionSet);
6683            }
6684        }
6685
6686        IntentFilter pkgFilter = new IntentFilter();
6687        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6688        pkgFilter.addDataScheme("package");
6689        mContext.registerReceiver(new BroadcastReceiver() {
6690            @Override
6691            public void onReceive(Context context, Intent intent) {
6692                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6693                if (pkgs != null) {
6694                    for (String pkg : pkgs) {
6695                        synchronized (ActivityManagerService.this) {
6696                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6697                                    0, "query restart")) {
6698                                setResultCode(Activity.RESULT_OK);
6699                                return;
6700                            }
6701                        }
6702                    }
6703                }
6704            }
6705        }, pkgFilter);
6706
6707        IntentFilter dumpheapFilter = new IntentFilter();
6708        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6709        mContext.registerReceiver(new BroadcastReceiver() {
6710            @Override
6711            public void onReceive(Context context, Intent intent) {
6712                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6713                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6714                } else {
6715                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6716                }
6717            }
6718        }, dumpheapFilter);
6719
6720        // Let system services know.
6721        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6722
6723        synchronized (this) {
6724            // Ensure that any processes we had put on hold are now started
6725            // up.
6726            final int NP = mProcessesOnHold.size();
6727            if (NP > 0) {
6728                ArrayList<ProcessRecord> procs =
6729                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6730                for (int ip=0; ip<NP; ip++) {
6731                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6732                            + procs.get(ip));
6733                    startProcessLocked(procs.get(ip), "on-hold", null);
6734                }
6735            }
6736
6737            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6738                // Start looking for apps that are abusing wake locks.
6739                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6740                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6741                // Tell anyone interested that we are done booting!
6742                SystemProperties.set("sys.boot_completed", "1");
6743
6744                // And trigger dev.bootcomplete if we are not showing encryption progress
6745                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6746                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6747                    SystemProperties.set("dev.bootcomplete", "1");
6748                }
6749                mUserController.sendBootCompletedLocked(
6750                        new IIntentReceiver.Stub() {
6751                            @Override
6752                            public void performReceive(Intent intent, int resultCode,
6753                                    String data, Bundle extras, boolean ordered,
6754                                    boolean sticky, int sendingUser) {
6755                                synchronized (ActivityManagerService.this) {
6756                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6757                                            true, false);
6758                                }
6759                            }
6760                        });
6761                scheduleStartProfilesLocked();
6762            }
6763        }
6764    }
6765
6766    @Override
6767    public void bootAnimationComplete() {
6768        final boolean callFinishBooting;
6769        synchronized (this) {
6770            callFinishBooting = mCallFinishBooting;
6771            mBootAnimationComplete = true;
6772        }
6773        if (callFinishBooting) {
6774            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6775            finishBooting();
6776            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6777        }
6778    }
6779
6780    final void ensureBootCompleted() {
6781        boolean booting;
6782        boolean enableScreen;
6783        synchronized (this) {
6784            booting = mBooting;
6785            mBooting = false;
6786            enableScreen = !mBooted;
6787            mBooted = true;
6788        }
6789
6790        if (booting) {
6791            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6792            finishBooting();
6793            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6794        }
6795
6796        if (enableScreen) {
6797            enableScreenAfterBoot();
6798        }
6799    }
6800
6801    @Override
6802    public final void activityResumed(IBinder token) {
6803        final long origId = Binder.clearCallingIdentity();
6804        synchronized(this) {
6805            ActivityRecord.activityResumedLocked(token);
6806        }
6807        Binder.restoreCallingIdentity(origId);
6808    }
6809
6810    @Override
6811    public final void activityPaused(IBinder token) {
6812        final long origId = Binder.clearCallingIdentity();
6813        synchronized(this) {
6814            ActivityStack stack = ActivityRecord.getStackLocked(token);
6815            if (stack != null) {
6816                stack.activityPausedLocked(token, false);
6817            }
6818        }
6819        Binder.restoreCallingIdentity(origId);
6820    }
6821
6822    @Override
6823    public final void activityStopped(IBinder token, Bundle icicle,
6824            PersistableBundle persistentState, CharSequence description) {
6825        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6826
6827        // Refuse possible leaked file descriptors
6828        if (icicle != null && icicle.hasFileDescriptors()) {
6829            throw new IllegalArgumentException("File descriptors passed in Bundle");
6830        }
6831
6832        final long origId = Binder.clearCallingIdentity();
6833
6834        synchronized (this) {
6835            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
6836            if (r != null) {
6837                r.activityStoppedLocked(icicle, persistentState, description);
6838            }
6839        }
6840
6841        trimApplications();
6842
6843        Binder.restoreCallingIdentity(origId);
6844    }
6845
6846    @Override
6847    public final void activityDestroyed(IBinder token) {
6848        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6849        synchronized (this) {
6850            ActivityStack stack = ActivityRecord.getStackLocked(token);
6851            if (stack != null) {
6852                stack.activityDestroyedLocked(token, "activityDestroyed");
6853            }
6854        }
6855    }
6856
6857    @Override
6858    public final void activityRelaunched(IBinder token) {
6859        final long origId = Binder.clearCallingIdentity();
6860        synchronized (this) {
6861            mStackSupervisor.activityRelaunchedLocked(token);
6862        }
6863        Binder.restoreCallingIdentity(origId);
6864    }
6865
6866    @Override
6867    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6868            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6869        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6870                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6871        synchronized (this) {
6872            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6873            if (record == null) {
6874                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6875                        + "found for: " + token);
6876            }
6877            record.setSizeConfigurations(horizontalSizeConfiguration,
6878                    verticalSizeConfigurations, smallestSizeConfigurations);
6879        }
6880    }
6881
6882    @Override
6883    public final void backgroundResourcesReleased(IBinder token) {
6884        final long origId = Binder.clearCallingIdentity();
6885        try {
6886            synchronized (this) {
6887                ActivityStack stack = ActivityRecord.getStackLocked(token);
6888                if (stack != null) {
6889                    stack.backgroundResourcesReleased();
6890                }
6891            }
6892        } finally {
6893            Binder.restoreCallingIdentity(origId);
6894        }
6895    }
6896
6897    @Override
6898    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6899        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6900    }
6901
6902    @Override
6903    public final void notifyEnterAnimationComplete(IBinder token) {
6904        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6905    }
6906
6907    @Override
6908    public String getCallingPackage(IBinder token) {
6909        synchronized (this) {
6910            ActivityRecord r = getCallingRecordLocked(token);
6911            return r != null ? r.info.packageName : null;
6912        }
6913    }
6914
6915    @Override
6916    public ComponentName getCallingActivity(IBinder token) {
6917        synchronized (this) {
6918            ActivityRecord r = getCallingRecordLocked(token);
6919            return r != null ? r.intent.getComponent() : null;
6920        }
6921    }
6922
6923    private ActivityRecord getCallingRecordLocked(IBinder token) {
6924        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6925        if (r == null) {
6926            return null;
6927        }
6928        return r.resultTo;
6929    }
6930
6931    @Override
6932    public ComponentName getActivityClassForToken(IBinder token) {
6933        synchronized(this) {
6934            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6935            if (r == null) {
6936                return null;
6937            }
6938            return r.intent.getComponent();
6939        }
6940    }
6941
6942    @Override
6943    public String getPackageForToken(IBinder token) {
6944        synchronized(this) {
6945            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6946            if (r == null) {
6947                return null;
6948            }
6949            return r.packageName;
6950        }
6951    }
6952
6953    @Override
6954    public boolean isRootVoiceInteraction(IBinder token) {
6955        synchronized(this) {
6956            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6957            if (r == null) {
6958                return false;
6959            }
6960            return r.rootVoiceInteraction;
6961        }
6962    }
6963
6964    @Override
6965    public IIntentSender getIntentSender(int type,
6966            String packageName, IBinder token, String resultWho,
6967            int requestCode, Intent[] intents, String[] resolvedTypes,
6968            int flags, Bundle bOptions, int userId) {
6969        enforceNotIsolatedCaller("getIntentSender");
6970        // Refuse possible leaked file descriptors
6971        if (intents != null) {
6972            if (intents.length < 1) {
6973                throw new IllegalArgumentException("Intents array length must be >= 1");
6974            }
6975            for (int i=0; i<intents.length; i++) {
6976                Intent intent = intents[i];
6977                if (intent != null) {
6978                    if (intent.hasFileDescriptors()) {
6979                        throw new IllegalArgumentException("File descriptors passed in Intent");
6980                    }
6981                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6982                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6983                        throw new IllegalArgumentException(
6984                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6985                    }
6986                    intents[i] = new Intent(intent);
6987                }
6988            }
6989            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6990                throw new IllegalArgumentException(
6991                        "Intent array length does not match resolvedTypes length");
6992            }
6993        }
6994        if (bOptions != null) {
6995            if (bOptions.hasFileDescriptors()) {
6996                throw new IllegalArgumentException("File descriptors passed in options");
6997            }
6998        }
6999
7000        synchronized(this) {
7001            int callingUid = Binder.getCallingUid();
7002            int origUserId = userId;
7003            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7004                    type == ActivityManager.INTENT_SENDER_BROADCAST,
7005                    ALLOW_NON_FULL, "getIntentSender", null);
7006            if (origUserId == UserHandle.USER_CURRENT) {
7007                // We don't want to evaluate this until the pending intent is
7008                // actually executed.  However, we do want to always do the
7009                // security checking for it above.
7010                userId = UserHandle.USER_CURRENT;
7011            }
7012            try {
7013                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7014                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7015                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7016                    if (!UserHandle.isSameApp(callingUid, uid)) {
7017                        String msg = "Permission Denial: getIntentSender() from pid="
7018                            + Binder.getCallingPid()
7019                            + ", uid=" + Binder.getCallingUid()
7020                            + ", (need uid=" + uid + ")"
7021                            + " is not allowed to send as package " + packageName;
7022                        Slog.w(TAG, msg);
7023                        throw new SecurityException(msg);
7024                    }
7025                }
7026
7027                return getIntentSenderLocked(type, packageName, callingUid, userId,
7028                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7029
7030            } catch (RemoteException e) {
7031                throw new SecurityException(e);
7032            }
7033        }
7034    }
7035
7036    IIntentSender getIntentSenderLocked(int type, String packageName,
7037            int callingUid, int userId, IBinder token, String resultWho,
7038            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7039            Bundle bOptions) {
7040        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7041        ActivityRecord activity = null;
7042        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7043            activity = ActivityRecord.isInStackLocked(token);
7044            if (activity == null) {
7045                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7046                return null;
7047            }
7048            if (activity.finishing) {
7049                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7050                return null;
7051            }
7052        }
7053
7054        // We're going to be splicing together extras before sending, so we're
7055        // okay poking into any contained extras.
7056        if (intents != null) {
7057            for (int i = 0; i < intents.length; i++) {
7058                intents[i].setDefusable(true);
7059            }
7060        }
7061        Bundle.setDefusable(bOptions, true);
7062
7063        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7064        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7065        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7066        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7067                |PendingIntent.FLAG_UPDATE_CURRENT);
7068
7069        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7070                type, packageName, activity, resultWho,
7071                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7072        WeakReference<PendingIntentRecord> ref;
7073        ref = mIntentSenderRecords.get(key);
7074        PendingIntentRecord rec = ref != null ? ref.get() : null;
7075        if (rec != null) {
7076            if (!cancelCurrent) {
7077                if (updateCurrent) {
7078                    if (rec.key.requestIntent != null) {
7079                        rec.key.requestIntent.replaceExtras(intents != null ?
7080                                intents[intents.length - 1] : null);
7081                    }
7082                    if (intents != null) {
7083                        intents[intents.length-1] = rec.key.requestIntent;
7084                        rec.key.allIntents = intents;
7085                        rec.key.allResolvedTypes = resolvedTypes;
7086                    } else {
7087                        rec.key.allIntents = null;
7088                        rec.key.allResolvedTypes = null;
7089                    }
7090                }
7091                return rec;
7092            }
7093            rec.canceled = true;
7094            mIntentSenderRecords.remove(key);
7095        }
7096        if (noCreate) {
7097            return rec;
7098        }
7099        rec = new PendingIntentRecord(this, key, callingUid);
7100        mIntentSenderRecords.put(key, rec.ref);
7101        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7102            if (activity.pendingResults == null) {
7103                activity.pendingResults
7104                        = new HashSet<WeakReference<PendingIntentRecord>>();
7105            }
7106            activity.pendingResults.add(rec.ref);
7107        }
7108        return rec;
7109    }
7110
7111    @Override
7112    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7113            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7114        if (target instanceof PendingIntentRecord) {
7115            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7116                    finishedReceiver, requiredPermission, options);
7117        } else {
7118            if (intent == null) {
7119                // Weird case: someone has given us their own custom IIntentSender, and now
7120                // they have someone else trying to send to it but of course this isn't
7121                // really a PendingIntent, so there is no base Intent, and the caller isn't
7122                // supplying an Intent... but we never want to dispatch a null Intent to
7123                // a receiver, so um...  let's make something up.
7124                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7125                intent = new Intent(Intent.ACTION_MAIN);
7126            }
7127            try {
7128                target.send(code, intent, resolvedType, null, requiredPermission, options);
7129            } catch (RemoteException e) {
7130            }
7131            // Platform code can rely on getting a result back when the send is done, but if
7132            // this intent sender is from outside of the system we can't rely on it doing that.
7133            // So instead we don't give it the result receiver, and instead just directly
7134            // report the finish immediately.
7135            if (finishedReceiver != null) {
7136                try {
7137                    finishedReceiver.performReceive(intent, 0,
7138                            null, null, false, false, UserHandle.getCallingUserId());
7139                } catch (RemoteException e) {
7140                }
7141            }
7142            return 0;
7143        }
7144    }
7145
7146    /**
7147     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7148     *
7149     * <p>{@code callerUid} must be allowed to request such whitelist by calling
7150     * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7151     */
7152    void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7153        if (DEBUG_WHITELISTS) {
7154            Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7155                    + targetUid + ", " + duration + ")");
7156        }
7157        synchronized (mPidsSelfLocked) {
7158            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7159            if (pr == null) {
7160                Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7161                return;
7162            }
7163            if (!pr.whitelistManager) {
7164                if (DEBUG_WHITELISTS) {
7165                    Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7166                            + callerPid + " is not allowed");
7167                }
7168                return;
7169            }
7170        }
7171
7172        final long token = Binder.clearCallingIdentity();
7173        try {
7174            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7175                    true, "pe from uid:" + callerUid);
7176        } finally {
7177            Binder.restoreCallingIdentity(token);
7178        }
7179    }
7180
7181    @Override
7182    public void cancelIntentSender(IIntentSender sender) {
7183        if (!(sender instanceof PendingIntentRecord)) {
7184            return;
7185        }
7186        synchronized(this) {
7187            PendingIntentRecord rec = (PendingIntentRecord)sender;
7188            try {
7189                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7190                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7191                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7192                    String msg = "Permission Denial: cancelIntentSender() from pid="
7193                        + Binder.getCallingPid()
7194                        + ", uid=" + Binder.getCallingUid()
7195                        + " is not allowed to cancel packges "
7196                        + rec.key.packageName;
7197                    Slog.w(TAG, msg);
7198                    throw new SecurityException(msg);
7199                }
7200            } catch (RemoteException e) {
7201                throw new SecurityException(e);
7202            }
7203            cancelIntentSenderLocked(rec, true);
7204        }
7205    }
7206
7207    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7208        rec.canceled = true;
7209        mIntentSenderRecords.remove(rec.key);
7210        if (cleanActivity && rec.key.activity != null) {
7211            rec.key.activity.pendingResults.remove(rec.ref);
7212        }
7213    }
7214
7215    @Override
7216    public String getPackageForIntentSender(IIntentSender pendingResult) {
7217        if (!(pendingResult instanceof PendingIntentRecord)) {
7218            return null;
7219        }
7220        try {
7221            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7222            return res.key.packageName;
7223        } catch (ClassCastException e) {
7224        }
7225        return null;
7226    }
7227
7228    @Override
7229    public int getUidForIntentSender(IIntentSender sender) {
7230        if (sender instanceof PendingIntentRecord) {
7231            try {
7232                PendingIntentRecord res = (PendingIntentRecord)sender;
7233                return res.uid;
7234            } catch (ClassCastException e) {
7235            }
7236        }
7237        return -1;
7238    }
7239
7240    @Override
7241    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7242        if (!(pendingResult instanceof PendingIntentRecord)) {
7243            return false;
7244        }
7245        try {
7246            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7247            if (res.key.allIntents == null) {
7248                return false;
7249            }
7250            for (int i=0; i<res.key.allIntents.length; i++) {
7251                Intent intent = res.key.allIntents[i];
7252                if (intent.getPackage() != null && intent.getComponent() != null) {
7253                    return false;
7254                }
7255            }
7256            return true;
7257        } catch (ClassCastException e) {
7258        }
7259        return false;
7260    }
7261
7262    @Override
7263    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7264        if (!(pendingResult instanceof PendingIntentRecord)) {
7265            return false;
7266        }
7267        try {
7268            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7269            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7270                return true;
7271            }
7272            return false;
7273        } catch (ClassCastException e) {
7274        }
7275        return false;
7276    }
7277
7278    @Override
7279    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7280        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7281                "getIntentForIntentSender()");
7282        if (!(pendingResult instanceof PendingIntentRecord)) {
7283            return null;
7284        }
7285        try {
7286            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7287            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7288        } catch (ClassCastException e) {
7289        }
7290        return null;
7291    }
7292
7293    @Override
7294    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7295        if (!(pendingResult instanceof PendingIntentRecord)) {
7296            return null;
7297        }
7298        try {
7299            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7300            synchronized (this) {
7301                return getTagForIntentSenderLocked(res, prefix);
7302            }
7303        } catch (ClassCastException e) {
7304        }
7305        return null;
7306    }
7307
7308    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7309        final Intent intent = res.key.requestIntent;
7310        if (intent != null) {
7311            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7312                    || res.lastTagPrefix.equals(prefix))) {
7313                return res.lastTag;
7314            }
7315            res.lastTagPrefix = prefix;
7316            final StringBuilder sb = new StringBuilder(128);
7317            if (prefix != null) {
7318                sb.append(prefix);
7319            }
7320            if (intent.getAction() != null) {
7321                sb.append(intent.getAction());
7322            } else if (intent.getComponent() != null) {
7323                intent.getComponent().appendShortString(sb);
7324            } else {
7325                sb.append("?");
7326            }
7327            return res.lastTag = sb.toString();
7328        }
7329        return null;
7330    }
7331
7332    @Override
7333    public void setProcessLimit(int max) {
7334        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7335                "setProcessLimit()");
7336        synchronized (this) {
7337            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7338            mProcessLimitOverride = max;
7339        }
7340        trimApplications();
7341    }
7342
7343    @Override
7344    public int getProcessLimit() {
7345        synchronized (this) {
7346            return mProcessLimitOverride;
7347        }
7348    }
7349
7350    void foregroundTokenDied(ForegroundToken token) {
7351        synchronized (ActivityManagerService.this) {
7352            synchronized (mPidsSelfLocked) {
7353                ForegroundToken cur
7354                    = mForegroundProcesses.get(token.pid);
7355                if (cur != token) {
7356                    return;
7357                }
7358                mForegroundProcesses.remove(token.pid);
7359                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7360                if (pr == null) {
7361                    return;
7362                }
7363                pr.forcingToForeground = null;
7364                updateProcessForegroundLocked(pr, false, false);
7365            }
7366            updateOomAdjLocked();
7367        }
7368    }
7369
7370    @Override
7371    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7372        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7373                "setProcessForeground()");
7374        synchronized(this) {
7375            boolean changed = false;
7376
7377            synchronized (mPidsSelfLocked) {
7378                ProcessRecord pr = mPidsSelfLocked.get(pid);
7379                if (pr == null && isForeground) {
7380                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7381                    return;
7382                }
7383                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7384                if (oldToken != null) {
7385                    oldToken.token.unlinkToDeath(oldToken, 0);
7386                    mForegroundProcesses.remove(pid);
7387                    if (pr != null) {
7388                        pr.forcingToForeground = null;
7389                    }
7390                    changed = true;
7391                }
7392                if (isForeground && token != null) {
7393                    ForegroundToken newToken = new ForegroundToken() {
7394                        @Override
7395                        public void binderDied() {
7396                            foregroundTokenDied(this);
7397                        }
7398                    };
7399                    newToken.pid = pid;
7400                    newToken.token = token;
7401                    try {
7402                        token.linkToDeath(newToken, 0);
7403                        mForegroundProcesses.put(pid, newToken);
7404                        pr.forcingToForeground = token;
7405                        changed = true;
7406                    } catch (RemoteException e) {
7407                        // If the process died while doing this, we will later
7408                        // do the cleanup with the process death link.
7409                    }
7410                }
7411            }
7412
7413            if (changed) {
7414                updateOomAdjLocked();
7415            }
7416        }
7417    }
7418
7419    @Override
7420    public boolean isAppForeground(int uid) throws RemoteException {
7421        synchronized (this) {
7422            UidRecord uidRec = mActiveUids.get(uid);
7423            if (uidRec == null || uidRec.idle) {
7424                return false;
7425            }
7426            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7427        }
7428    }
7429
7430    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7431    // be guarded by permission checking.
7432    int getUidState(int uid) {
7433        synchronized (this) {
7434            UidRecord uidRec = mActiveUids.get(uid);
7435            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7436        }
7437    }
7438
7439    @Override
7440    public boolean isInMultiWindowMode(IBinder token) {
7441        final long origId = Binder.clearCallingIdentity();
7442        try {
7443            synchronized(this) {
7444                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7445                if (r == null) {
7446                    return false;
7447                }
7448                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7449                return !r.task.mFullscreen;
7450            }
7451        } finally {
7452            Binder.restoreCallingIdentity(origId);
7453        }
7454    }
7455
7456    @Override
7457    public boolean isInPictureInPictureMode(IBinder token) {
7458        final long origId = Binder.clearCallingIdentity();
7459        try {
7460            synchronized(this) {
7461                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7462                if (stack == null) {
7463                    return false;
7464                }
7465                return stack.mStackId == PINNED_STACK_ID;
7466            }
7467        } finally {
7468            Binder.restoreCallingIdentity(origId);
7469        }
7470    }
7471
7472    @Override
7473    public void enterPictureInPictureMode(IBinder token) {
7474        final long origId = Binder.clearCallingIdentity();
7475        try {
7476            synchronized(this) {
7477                if (!mSupportsPictureInPicture) {
7478                    throw new IllegalStateException("enterPictureInPictureMode: "
7479                            + "Device doesn't support picture-in-picture mode.");
7480                }
7481
7482                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7483
7484                if (r == null) {
7485                    throw new IllegalStateException("enterPictureInPictureMode: "
7486                            + "Can't find activity for token=" + token);
7487                }
7488
7489                if (!r.supportsPictureInPicture()) {
7490                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7491                            + "Picture-In-Picture not supported for r=" + r);
7492                }
7493
7494                // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7495                // current bounds.
7496                final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7497                final Rect bounds = (pinnedStack != null)
7498                        ? pinnedStack.mBounds : getDefaultPictureInPictureBounds(DEFAULT_DISPLAY);
7499
7500                mStackSupervisor.moveActivityToPinnedStackLocked(
7501                        r, "enterPictureInPictureMode", bounds);
7502            }
7503        } finally {
7504            Binder.restoreCallingIdentity(origId);
7505        }
7506    }
7507
7508    @Override
7509    public Rect getDefaultPictureInPictureBounds(int displayId) {
7510        final long origId = Binder.clearCallingIdentity();
7511        final Rect defaultBounds = new Rect();
7512        try {
7513            synchronized(this) {
7514                if (!mSupportsPictureInPicture) {
7515                    return new Rect();
7516                }
7517
7518                // Convert the sizes to for the current display state
7519                final DisplayMetrics dm = mStackSupervisor.getDisplayRealMetrics(displayId);
7520                final int stackWidth = (int) TypedValue.applyDimension(COMPLEX_UNIT_DIP,
7521                        mDefaultPinnedStackSizeDp.getWidth(), dm);
7522                final int stackHeight = (int) TypedValue.applyDimension(COMPLEX_UNIT_DIP,
7523                        mDefaultPinnedStackSizeDp.getHeight(), dm);
7524                final Rect maxBounds = new Rect();
7525                getPictureInPictureBounds(displayId, maxBounds);
7526                Gravity.apply(mDefaultPinnedStackGravity, stackWidth, stackHeight,
7527                        maxBounds, 0, 0, defaultBounds);
7528            }
7529        } finally {
7530            Binder.restoreCallingIdentity(origId);
7531        }
7532        return defaultBounds;
7533    }
7534
7535    @Override
7536    public Rect getPictureInPictureMovementBounds(int displayId) {
7537        final long origId = Binder.clearCallingIdentity();
7538        final Rect maxBounds = new Rect();
7539        try {
7540            synchronized(this) {
7541                if (!mSupportsPictureInPicture) {
7542                    return new Rect();
7543                }
7544
7545                getPictureInPictureBounds(displayId, maxBounds);
7546
7547                // Adjust the max bounds by the current stack dimensions
7548                final StackInfo pinnedStackInfo = mStackSupervisor.getStackInfoLocked(
7549                        PINNED_STACK_ID);
7550                if (pinnedStackInfo != null) {
7551                    maxBounds.right = Math.max(maxBounds.left, maxBounds.right -
7552                            pinnedStackInfo.bounds.width());
7553                    maxBounds.bottom = Math.max(maxBounds.top, maxBounds.bottom -
7554                            pinnedStackInfo.bounds.height());
7555                }
7556            }
7557        } finally {
7558            Binder.restoreCallingIdentity(origId);
7559        }
7560        return maxBounds;
7561    }
7562
7563    /**
7564     * Calculate the bounds where the pinned stack can move in the current display state.
7565     */
7566    private void getPictureInPictureBounds(int displayId, Rect outRect) {
7567        // Convert the insets to for the current display state
7568        final DisplayMetrics dm = mStackSupervisor.getDisplayRealMetrics(displayId);
7569        final int insetsLR = (int) TypedValue.applyDimension(COMPLEX_UNIT_DIP,
7570                mDefaultPinnedStackScreenEdgeInsetsDp.getWidth(), dm);
7571        final int insetsTB = (int) TypedValue.applyDimension(COMPLEX_UNIT_DIP,
7572                mDefaultPinnedStackScreenEdgeInsetsDp.getHeight(), dm);
7573        try {
7574            final Point displaySize = mStackSupervisor.getDisplayRealSize(displayId);
7575            final Rect insets = new Rect();
7576            mWindowManager.getStableInsets(displayId, insets);
7577
7578            // Calculate the insets from the system decorations and apply the gravity
7579            outRect.set(insets.left + insetsLR, insets.top + insetsTB,
7580                    displaySize.x - insets.right - insetsLR,
7581                    displaySize.y - insets.bottom - insetsTB);
7582        } catch (RemoteException e) {
7583            Log.e(TAG, "Failed to calculate PIP movement bounds", e);
7584        }
7585    }
7586
7587    // =========================================================
7588    // PROCESS INFO
7589    // =========================================================
7590
7591    static class ProcessInfoService extends IProcessInfoService.Stub {
7592        final ActivityManagerService mActivityManagerService;
7593        ProcessInfoService(ActivityManagerService activityManagerService) {
7594            mActivityManagerService = activityManagerService;
7595        }
7596
7597        @Override
7598        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7599            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7600                    /*in*/ pids, /*out*/ states, null);
7601        }
7602
7603        @Override
7604        public void getProcessStatesAndOomScoresFromPids(
7605                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7606            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7607                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7608        }
7609    }
7610
7611    /**
7612     * For each PID in the given input array, write the current process state
7613     * for that process into the states array, or -1 to indicate that no
7614     * process with the given PID exists. If scores array is provided, write
7615     * the oom score for the process into the scores array, with INVALID_ADJ
7616     * indicating the PID doesn't exist.
7617     */
7618    public void getProcessStatesAndOomScoresForPIDs(
7619            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7620        if (scores != null) {
7621            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7622                    "getProcessStatesAndOomScoresForPIDs()");
7623        }
7624
7625        if (pids == null) {
7626            throw new NullPointerException("pids");
7627        } else if (states == null) {
7628            throw new NullPointerException("states");
7629        } else if (pids.length != states.length) {
7630            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7631        } else if (scores != null && pids.length != scores.length) {
7632            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7633        }
7634
7635        synchronized (mPidsSelfLocked) {
7636            for (int i = 0; i < pids.length; i++) {
7637                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7638                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7639                        pr.curProcState;
7640                if (scores != null) {
7641                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7642                }
7643            }
7644        }
7645    }
7646
7647    // =========================================================
7648    // PERMISSIONS
7649    // =========================================================
7650
7651    static class PermissionController extends IPermissionController.Stub {
7652        ActivityManagerService mActivityManagerService;
7653        PermissionController(ActivityManagerService activityManagerService) {
7654            mActivityManagerService = activityManagerService;
7655        }
7656
7657        @Override
7658        public boolean checkPermission(String permission, int pid, int uid) {
7659            return mActivityManagerService.checkPermission(permission, pid,
7660                    uid) == PackageManager.PERMISSION_GRANTED;
7661        }
7662
7663        @Override
7664        public String[] getPackagesForUid(int uid) {
7665            return mActivityManagerService.mContext.getPackageManager()
7666                    .getPackagesForUid(uid);
7667        }
7668
7669        @Override
7670        public boolean isRuntimePermission(String permission) {
7671            try {
7672                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7673                        .getPermissionInfo(permission, 0);
7674                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7675            } catch (NameNotFoundException nnfe) {
7676                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7677            }
7678            return false;
7679        }
7680    }
7681
7682    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7683        @Override
7684        public int checkComponentPermission(String permission, int pid, int uid,
7685                int owningUid, boolean exported) {
7686            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7687                    owningUid, exported);
7688        }
7689
7690        @Override
7691        public Object getAMSLock() {
7692            return ActivityManagerService.this;
7693        }
7694    }
7695
7696    /**
7697     * This can be called with or without the global lock held.
7698     */
7699    int checkComponentPermission(String permission, int pid, int uid,
7700            int owningUid, boolean exported) {
7701        if (pid == MY_PID) {
7702            return PackageManager.PERMISSION_GRANTED;
7703        }
7704        return ActivityManager.checkComponentPermission(permission, uid,
7705                owningUid, exported);
7706    }
7707
7708    /**
7709     * As the only public entry point for permissions checking, this method
7710     * can enforce the semantic that requesting a check on a null global
7711     * permission is automatically denied.  (Internally a null permission
7712     * string is used when calling {@link #checkComponentPermission} in cases
7713     * when only uid-based security is needed.)
7714     *
7715     * This can be called with or without the global lock held.
7716     */
7717    @Override
7718    public int checkPermission(String permission, int pid, int uid) {
7719        if (permission == null) {
7720            return PackageManager.PERMISSION_DENIED;
7721        }
7722        return checkComponentPermission(permission, pid, uid, -1, true);
7723    }
7724
7725    @Override
7726    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7727        if (permission == null) {
7728            return PackageManager.PERMISSION_DENIED;
7729        }
7730
7731        // We might be performing an operation on behalf of an indirect binder
7732        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7733        // client identity accordingly before proceeding.
7734        Identity tlsIdentity = sCallerIdentity.get();
7735        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7736            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7737                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7738            uid = tlsIdentity.uid;
7739            pid = tlsIdentity.pid;
7740        }
7741
7742        return checkComponentPermission(permission, pid, uid, -1, true);
7743    }
7744
7745    /**
7746     * Binder IPC calls go through the public entry point.
7747     * This can be called with or without the global lock held.
7748     */
7749    int checkCallingPermission(String permission) {
7750        return checkPermission(permission,
7751                Binder.getCallingPid(),
7752                UserHandle.getAppId(Binder.getCallingUid()));
7753    }
7754
7755    /**
7756     * This can be called with or without the global lock held.
7757     */
7758    void enforceCallingPermission(String permission, String func) {
7759        if (checkCallingPermission(permission)
7760                == PackageManager.PERMISSION_GRANTED) {
7761            return;
7762        }
7763
7764        String msg = "Permission Denial: " + func + " from pid="
7765                + Binder.getCallingPid()
7766                + ", uid=" + Binder.getCallingUid()
7767                + " requires " + permission;
7768        Slog.w(TAG, msg);
7769        throw new SecurityException(msg);
7770    }
7771
7772    /**
7773     * Determine if UID is holding permissions required to access {@link Uri} in
7774     * the given {@link ProviderInfo}. Final permission checking is always done
7775     * in {@link ContentProvider}.
7776     */
7777    private final boolean checkHoldingPermissionsLocked(
7778            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7779        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7780                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7781        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7782            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7783                    != PERMISSION_GRANTED) {
7784                return false;
7785            }
7786        }
7787        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7788    }
7789
7790    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7791            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7792        if (pi.applicationInfo.uid == uid) {
7793            return true;
7794        } else if (!pi.exported) {
7795            return false;
7796        }
7797
7798        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7799        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7800        try {
7801            // check if target holds top-level <provider> permissions
7802            if (!readMet && pi.readPermission != null && considerUidPermissions
7803                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7804                readMet = true;
7805            }
7806            if (!writeMet && pi.writePermission != null && considerUidPermissions
7807                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7808                writeMet = true;
7809            }
7810
7811            // track if unprotected read/write is allowed; any denied
7812            // <path-permission> below removes this ability
7813            boolean allowDefaultRead = pi.readPermission == null;
7814            boolean allowDefaultWrite = pi.writePermission == null;
7815
7816            // check if target holds any <path-permission> that match uri
7817            final PathPermission[] pps = pi.pathPermissions;
7818            if (pps != null) {
7819                final String path = grantUri.uri.getPath();
7820                int i = pps.length;
7821                while (i > 0 && (!readMet || !writeMet)) {
7822                    i--;
7823                    PathPermission pp = pps[i];
7824                    if (pp.match(path)) {
7825                        if (!readMet) {
7826                            final String pprperm = pp.getReadPermission();
7827                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7828                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7829                                    + ": match=" + pp.match(path)
7830                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7831                            if (pprperm != null) {
7832                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7833                                        == PERMISSION_GRANTED) {
7834                                    readMet = true;
7835                                } else {
7836                                    allowDefaultRead = false;
7837                                }
7838                            }
7839                        }
7840                        if (!writeMet) {
7841                            final String ppwperm = pp.getWritePermission();
7842                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7843                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7844                                    + ": match=" + pp.match(path)
7845                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7846                            if (ppwperm != null) {
7847                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7848                                        == PERMISSION_GRANTED) {
7849                                    writeMet = true;
7850                                } else {
7851                                    allowDefaultWrite = false;
7852                                }
7853                            }
7854                        }
7855                    }
7856                }
7857            }
7858
7859            // grant unprotected <provider> read/write, if not blocked by
7860            // <path-permission> above
7861            if (allowDefaultRead) readMet = true;
7862            if (allowDefaultWrite) writeMet = true;
7863
7864        } catch (RemoteException e) {
7865            return false;
7866        }
7867
7868        return readMet && writeMet;
7869    }
7870
7871    public int getAppStartMode(int uid, String packageName) {
7872        synchronized (this) {
7873            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7874        }
7875    }
7876
7877    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7878            boolean allowWhenForeground) {
7879        UidRecord uidRec = mActiveUids.get(uid);
7880        if (!mLenientBackgroundCheck) {
7881            if (!allowWhenForeground || uidRec == null
7882                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7883                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7884                        packageName) != AppOpsManager.MODE_ALLOWED) {
7885                    return ActivityManager.APP_START_MODE_DELAYED;
7886                }
7887            }
7888
7889        } else if (uidRec == null || uidRec.idle) {
7890            if (callingPid >= 0) {
7891                ProcessRecord proc;
7892                synchronized (mPidsSelfLocked) {
7893                    proc = mPidsSelfLocked.get(callingPid);
7894                }
7895                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7896                    // Whoever is instigating this is in the foreground, so we will allow it
7897                    // to go through.
7898                    return ActivityManager.APP_START_MODE_NORMAL;
7899                }
7900            }
7901            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7902                    != AppOpsManager.MODE_ALLOWED) {
7903                return ActivityManager.APP_START_MODE_DELAYED;
7904            }
7905        }
7906        return ActivityManager.APP_START_MODE_NORMAL;
7907    }
7908
7909    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
7910        ProviderInfo pi = null;
7911        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7912        if (cpr != null) {
7913            pi = cpr.info;
7914        } else {
7915            try {
7916                pi = AppGlobals.getPackageManager().resolveContentProvider(
7917                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
7918                        userHandle);
7919            } catch (RemoteException ex) {
7920            }
7921        }
7922        return pi;
7923    }
7924
7925    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7926        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7927        if (targetUris != null) {
7928            return targetUris.get(grantUri);
7929        }
7930        return null;
7931    }
7932
7933    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7934            String targetPkg, int targetUid, GrantUri grantUri) {
7935        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7936        if (targetUris == null) {
7937            targetUris = Maps.newArrayMap();
7938            mGrantedUriPermissions.put(targetUid, targetUris);
7939        }
7940
7941        UriPermission perm = targetUris.get(grantUri);
7942        if (perm == null) {
7943            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7944            targetUris.put(grantUri, perm);
7945        }
7946
7947        return perm;
7948    }
7949
7950    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7951            final int modeFlags) {
7952        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7953        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7954                : UriPermission.STRENGTH_OWNED;
7955
7956        // Root gets to do everything.
7957        if (uid == 0) {
7958            return true;
7959        }
7960
7961        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7962        if (perms == null) return false;
7963
7964        // First look for exact match
7965        final UriPermission exactPerm = perms.get(grantUri);
7966        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7967            return true;
7968        }
7969
7970        // No exact match, look for prefixes
7971        final int N = perms.size();
7972        for (int i = 0; i < N; i++) {
7973            final UriPermission perm = perms.valueAt(i);
7974            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7975                    && perm.getStrength(modeFlags) >= minStrength) {
7976                return true;
7977            }
7978        }
7979
7980        return false;
7981    }
7982
7983    /**
7984     * @param uri This uri must NOT contain an embedded userId.
7985     * @param userId The userId in which the uri is to be resolved.
7986     */
7987    @Override
7988    public int checkUriPermission(Uri uri, int pid, int uid,
7989            final int modeFlags, int userId, IBinder callerToken) {
7990        enforceNotIsolatedCaller("checkUriPermission");
7991
7992        // Another redirected-binder-call permissions check as in
7993        // {@link checkPermissionWithToken}.
7994        Identity tlsIdentity = sCallerIdentity.get();
7995        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7996            uid = tlsIdentity.uid;
7997            pid = tlsIdentity.pid;
7998        }
7999
8000        // Our own process gets to do everything.
8001        if (pid == MY_PID) {
8002            return PackageManager.PERMISSION_GRANTED;
8003        }
8004        synchronized (this) {
8005            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8006                    ? PackageManager.PERMISSION_GRANTED
8007                    : PackageManager.PERMISSION_DENIED;
8008        }
8009    }
8010
8011    /**
8012     * Check if the targetPkg can be granted permission to access uri by
8013     * the callingUid using the given modeFlags.  Throws a security exception
8014     * if callingUid is not allowed to do this.  Returns the uid of the target
8015     * if the URI permission grant should be performed; returns -1 if it is not
8016     * needed (for example targetPkg already has permission to access the URI).
8017     * If you already know the uid of the target, you can supply it in
8018     * lastTargetUid else set that to -1.
8019     */
8020    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8021            final int modeFlags, int lastTargetUid) {
8022        if (!Intent.isAccessUriMode(modeFlags)) {
8023            return -1;
8024        }
8025
8026        if (targetPkg != null) {
8027            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8028                    "Checking grant " + targetPkg + " permission to " + grantUri);
8029        }
8030
8031        final IPackageManager pm = AppGlobals.getPackageManager();
8032
8033        // If this is not a content: uri, we can't do anything with it.
8034        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8035            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8036                    "Can't grant URI permission for non-content URI: " + grantUri);
8037            return -1;
8038        }
8039
8040        final String authority = grantUri.uri.getAuthority();
8041        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8042                MATCH_DEBUG_TRIAGED_MISSING);
8043        if (pi == null) {
8044            Slog.w(TAG, "No content provider found for permission check: " +
8045                    grantUri.uri.toSafeString());
8046            return -1;
8047        }
8048
8049        int targetUid = lastTargetUid;
8050        if (targetUid < 0 && targetPkg != null) {
8051            try {
8052                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8053                        UserHandle.getUserId(callingUid));
8054                if (targetUid < 0) {
8055                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8056                            "Can't grant URI permission no uid for: " + targetPkg);
8057                    return -1;
8058                }
8059            } catch (RemoteException ex) {
8060                return -1;
8061            }
8062        }
8063
8064        if (targetUid >= 0) {
8065            // First...  does the target actually need this permission?
8066            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8067                // No need to grant the target this permission.
8068                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8069                        "Target " + targetPkg + " already has full permission to " + grantUri);
8070                return -1;
8071            }
8072        } else {
8073            // First...  there is no target package, so can anyone access it?
8074            boolean allowed = pi.exported;
8075            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8076                if (pi.readPermission != null) {
8077                    allowed = false;
8078                }
8079            }
8080            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8081                if (pi.writePermission != null) {
8082                    allowed = false;
8083                }
8084            }
8085            if (allowed) {
8086                return -1;
8087            }
8088        }
8089
8090        /* There is a special cross user grant if:
8091         * - The target is on another user.
8092         * - Apps on the current user can access the uri without any uid permissions.
8093         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8094         * grant uri permissions.
8095         */
8096        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8097                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8098                modeFlags, false /*without considering the uid permissions*/);
8099
8100        // Second...  is the provider allowing granting of URI permissions?
8101        if (!specialCrossUserGrant) {
8102            if (!pi.grantUriPermissions) {
8103                throw new SecurityException("Provider " + pi.packageName
8104                        + "/" + pi.name
8105                        + " does not allow granting of Uri permissions (uri "
8106                        + grantUri + ")");
8107            }
8108            if (pi.uriPermissionPatterns != null) {
8109                final int N = pi.uriPermissionPatterns.length;
8110                boolean allowed = false;
8111                for (int i=0; i<N; i++) {
8112                    if (pi.uriPermissionPatterns[i] != null
8113                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8114                        allowed = true;
8115                        break;
8116                    }
8117                }
8118                if (!allowed) {
8119                    throw new SecurityException("Provider " + pi.packageName
8120                            + "/" + pi.name
8121                            + " does not allow granting of permission to path of Uri "
8122                            + grantUri);
8123                }
8124            }
8125        }
8126
8127        // Third...  does the caller itself have permission to access
8128        // this uri?
8129        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
8130            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8131                // Require they hold a strong enough Uri permission
8132                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8133                    throw new SecurityException("Uid " + callingUid
8134                            + " does not have permission to uri " + grantUri);
8135                }
8136            }
8137        }
8138        return targetUid;
8139    }
8140
8141    /**
8142     * @param uri This uri must NOT contain an embedded userId.
8143     * @param userId The userId in which the uri is to be resolved.
8144     */
8145    @Override
8146    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8147            final int modeFlags, int userId) {
8148        enforceNotIsolatedCaller("checkGrantUriPermission");
8149        synchronized(this) {
8150            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8151                    new GrantUri(userId, uri, false), modeFlags, -1);
8152        }
8153    }
8154
8155    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8156            final int modeFlags, UriPermissionOwner owner) {
8157        if (!Intent.isAccessUriMode(modeFlags)) {
8158            return;
8159        }
8160
8161        // So here we are: the caller has the assumed permission
8162        // to the uri, and the target doesn't.  Let's now give this to
8163        // the target.
8164
8165        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8166                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8167
8168        final String authority = grantUri.uri.getAuthority();
8169        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8170                MATCH_DEBUG_TRIAGED_MISSING);
8171        if (pi == null) {
8172            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8173            return;
8174        }
8175
8176        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8177            grantUri.prefix = true;
8178        }
8179        final UriPermission perm = findOrCreateUriPermissionLocked(
8180                pi.packageName, targetPkg, targetUid, grantUri);
8181        perm.grantModes(modeFlags, owner);
8182    }
8183
8184    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8185            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8186        if (targetPkg == null) {
8187            throw new NullPointerException("targetPkg");
8188        }
8189        int targetUid;
8190        final IPackageManager pm = AppGlobals.getPackageManager();
8191        try {
8192            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8193        } catch (RemoteException ex) {
8194            return;
8195        }
8196
8197        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8198                targetUid);
8199        if (targetUid < 0) {
8200            return;
8201        }
8202
8203        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8204                owner);
8205    }
8206
8207    static class NeededUriGrants extends ArrayList<GrantUri> {
8208        final String targetPkg;
8209        final int targetUid;
8210        final int flags;
8211
8212        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8213            this.targetPkg = targetPkg;
8214            this.targetUid = targetUid;
8215            this.flags = flags;
8216        }
8217    }
8218
8219    /**
8220     * Like checkGrantUriPermissionLocked, but takes an Intent.
8221     */
8222    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8223            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8224        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8225                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8226                + " clip=" + (intent != null ? intent.getClipData() : null)
8227                + " from " + intent + "; flags=0x"
8228                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8229
8230        if (targetPkg == null) {
8231            throw new NullPointerException("targetPkg");
8232        }
8233
8234        if (intent == null) {
8235            return null;
8236        }
8237        Uri data = intent.getData();
8238        ClipData clip = intent.getClipData();
8239        if (data == null && clip == null) {
8240            return null;
8241        }
8242        // Default userId for uris in the intent (if they don't specify it themselves)
8243        int contentUserHint = intent.getContentUserHint();
8244        if (contentUserHint == UserHandle.USER_CURRENT) {
8245            contentUserHint = UserHandle.getUserId(callingUid);
8246        }
8247        final IPackageManager pm = AppGlobals.getPackageManager();
8248        int targetUid;
8249        if (needed != null) {
8250            targetUid = needed.targetUid;
8251        } else {
8252            try {
8253                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8254                        targetUserId);
8255            } catch (RemoteException ex) {
8256                return null;
8257            }
8258            if (targetUid < 0) {
8259                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8260                        "Can't grant URI permission no uid for: " + targetPkg
8261                        + " on user " + targetUserId);
8262                return null;
8263            }
8264        }
8265        if (data != null) {
8266            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8267            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8268                    targetUid);
8269            if (targetUid > 0) {
8270                if (needed == null) {
8271                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8272                }
8273                needed.add(grantUri);
8274            }
8275        }
8276        if (clip != null) {
8277            for (int i=0; i<clip.getItemCount(); i++) {
8278                Uri uri = clip.getItemAt(i).getUri();
8279                if (uri != null) {
8280                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8281                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8282                            targetUid);
8283                    if (targetUid > 0) {
8284                        if (needed == null) {
8285                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8286                        }
8287                        needed.add(grantUri);
8288                    }
8289                } else {
8290                    Intent clipIntent = clip.getItemAt(i).getIntent();
8291                    if (clipIntent != null) {
8292                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8293                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8294                        if (newNeeded != null) {
8295                            needed = newNeeded;
8296                        }
8297                    }
8298                }
8299            }
8300        }
8301
8302        return needed;
8303    }
8304
8305    /**
8306     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8307     */
8308    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8309            UriPermissionOwner owner) {
8310        if (needed != null) {
8311            for (int i=0; i<needed.size(); i++) {
8312                GrantUri grantUri = needed.get(i);
8313                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8314                        grantUri, needed.flags, owner);
8315            }
8316        }
8317    }
8318
8319    void grantUriPermissionFromIntentLocked(int callingUid,
8320            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8321        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8322                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8323        if (needed == null) {
8324            return;
8325        }
8326
8327        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8328    }
8329
8330    /**
8331     * @param uri This uri must NOT contain an embedded userId.
8332     * @param userId The userId in which the uri is to be resolved.
8333     */
8334    @Override
8335    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8336            final int modeFlags, int userId) {
8337        enforceNotIsolatedCaller("grantUriPermission");
8338        GrantUri grantUri = new GrantUri(userId, uri, false);
8339        synchronized(this) {
8340            final ProcessRecord r = getRecordForAppLocked(caller);
8341            if (r == null) {
8342                throw new SecurityException("Unable to find app for caller "
8343                        + caller
8344                        + " when granting permission to uri " + grantUri);
8345            }
8346            if (targetPkg == null) {
8347                throw new IllegalArgumentException("null target");
8348            }
8349            if (grantUri == null) {
8350                throw new IllegalArgumentException("null uri");
8351            }
8352
8353            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8354                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8355                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8356                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8357
8358            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8359                    UserHandle.getUserId(r.uid));
8360        }
8361    }
8362
8363    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8364        if (perm.modeFlags == 0) {
8365            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8366                    perm.targetUid);
8367            if (perms != null) {
8368                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8369                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8370
8371                perms.remove(perm.uri);
8372                if (perms.isEmpty()) {
8373                    mGrantedUriPermissions.remove(perm.targetUid);
8374                }
8375            }
8376        }
8377    }
8378
8379    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8380        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8381                "Revoking all granted permissions to " + grantUri);
8382
8383        final IPackageManager pm = AppGlobals.getPackageManager();
8384        final String authority = grantUri.uri.getAuthority();
8385        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8386                MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8387        if (pi == null) {
8388            Slog.w(TAG, "No content provider found for permission revoke: "
8389                    + grantUri.toSafeString());
8390            return;
8391        }
8392
8393        // Does the caller have this permission on the URI?
8394        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8395            // If they don't have direct access to the URI, then revoke any
8396            // ownerless URI permissions that have been granted to them.
8397            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8398            if (perms != null) {
8399                boolean persistChanged = false;
8400                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8401                    final UriPermission perm = it.next();
8402                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8403                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8404                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8405                                "Revoking non-owned " + perm.targetUid
8406                                + " permission to " + perm.uri);
8407                        persistChanged |= perm.revokeModes(
8408                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8409                        if (perm.modeFlags == 0) {
8410                            it.remove();
8411                        }
8412                    }
8413                }
8414                if (perms.isEmpty()) {
8415                    mGrantedUriPermissions.remove(callingUid);
8416                }
8417                if (persistChanged) {
8418                    schedulePersistUriGrants();
8419                }
8420            }
8421            return;
8422        }
8423
8424        boolean persistChanged = false;
8425
8426        // Go through all of the permissions and remove any that match.
8427        int N = mGrantedUriPermissions.size();
8428        for (int i = 0; i < N; i++) {
8429            final int targetUid = mGrantedUriPermissions.keyAt(i);
8430            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8431
8432            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8433                final UriPermission perm = it.next();
8434                if (perm.uri.sourceUserId == grantUri.sourceUserId
8435                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8436                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8437                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8438                    persistChanged |= perm.revokeModes(
8439                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8440                    if (perm.modeFlags == 0) {
8441                        it.remove();
8442                    }
8443                }
8444            }
8445
8446            if (perms.isEmpty()) {
8447                mGrantedUriPermissions.remove(targetUid);
8448                N--;
8449                i--;
8450            }
8451        }
8452
8453        if (persistChanged) {
8454            schedulePersistUriGrants();
8455        }
8456    }
8457
8458    /**
8459     * @param uri This uri must NOT contain an embedded userId.
8460     * @param userId The userId in which the uri is to be resolved.
8461     */
8462    @Override
8463    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8464            int userId) {
8465        enforceNotIsolatedCaller("revokeUriPermission");
8466        synchronized(this) {
8467            final ProcessRecord r = getRecordForAppLocked(caller);
8468            if (r == null) {
8469                throw new SecurityException("Unable to find app for caller "
8470                        + caller
8471                        + " when revoking permission to uri " + uri);
8472            }
8473            if (uri == null) {
8474                Slog.w(TAG, "revokeUriPermission: null uri");
8475                return;
8476            }
8477
8478            if (!Intent.isAccessUriMode(modeFlags)) {
8479                return;
8480            }
8481
8482            final String authority = uri.getAuthority();
8483            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8484                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8485            if (pi == null) {
8486                Slog.w(TAG, "No content provider found for permission revoke: "
8487                        + uri.toSafeString());
8488                return;
8489            }
8490
8491            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8492        }
8493    }
8494
8495    /**
8496     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8497     * given package.
8498     *
8499     * @param packageName Package name to match, or {@code null} to apply to all
8500     *            packages.
8501     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8502     *            to all users.
8503     * @param persistable If persistable grants should be removed.
8504     */
8505    private void removeUriPermissionsForPackageLocked(
8506            String packageName, int userHandle, boolean persistable) {
8507        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8508            throw new IllegalArgumentException("Must narrow by either package or user");
8509        }
8510
8511        boolean persistChanged = false;
8512
8513        int N = mGrantedUriPermissions.size();
8514        for (int i = 0; i < N; i++) {
8515            final int targetUid = mGrantedUriPermissions.keyAt(i);
8516            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8517
8518            // Only inspect grants matching user
8519            if (userHandle == UserHandle.USER_ALL
8520                    || userHandle == UserHandle.getUserId(targetUid)) {
8521                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8522                    final UriPermission perm = it.next();
8523
8524                    // Only inspect grants matching package
8525                    if (packageName == null || perm.sourcePkg.equals(packageName)
8526                            || perm.targetPkg.equals(packageName)) {
8527                        persistChanged |= perm.revokeModes(persistable
8528                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8529
8530                        // Only remove when no modes remain; any persisted grants
8531                        // will keep this alive.
8532                        if (perm.modeFlags == 0) {
8533                            it.remove();
8534                        }
8535                    }
8536                }
8537
8538                if (perms.isEmpty()) {
8539                    mGrantedUriPermissions.remove(targetUid);
8540                    N--;
8541                    i--;
8542                }
8543            }
8544        }
8545
8546        if (persistChanged) {
8547            schedulePersistUriGrants();
8548        }
8549    }
8550
8551    @Override
8552    public IBinder newUriPermissionOwner(String name) {
8553        enforceNotIsolatedCaller("newUriPermissionOwner");
8554        synchronized(this) {
8555            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8556            return owner.getExternalTokenLocked();
8557        }
8558    }
8559
8560    @Override
8561    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8562        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8563        synchronized(this) {
8564            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8565            if (r == null) {
8566                throw new IllegalArgumentException("Activity does not exist; token="
8567                        + activityToken);
8568            }
8569            return r.getUriPermissionsLocked().getExternalTokenLocked();
8570        }
8571    }
8572    /**
8573     * @param uri This uri must NOT contain an embedded userId.
8574     * @param sourceUserId The userId in which the uri is to be resolved.
8575     * @param targetUserId The userId of the app that receives the grant.
8576     */
8577    @Override
8578    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8579            final int modeFlags, int sourceUserId, int targetUserId) {
8580        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8581                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8582                "grantUriPermissionFromOwner", null);
8583        synchronized(this) {
8584            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8585            if (owner == null) {
8586                throw new IllegalArgumentException("Unknown owner: " + token);
8587            }
8588            if (fromUid != Binder.getCallingUid()) {
8589                if (Binder.getCallingUid() != Process.myUid()) {
8590                    // Only system code can grant URI permissions on behalf
8591                    // of other users.
8592                    throw new SecurityException("nice try");
8593                }
8594            }
8595            if (targetPkg == null) {
8596                throw new IllegalArgumentException("null target");
8597            }
8598            if (uri == null) {
8599                throw new IllegalArgumentException("null uri");
8600            }
8601
8602            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8603                    modeFlags, owner, targetUserId);
8604        }
8605    }
8606
8607    /**
8608     * @param uri This uri must NOT contain an embedded userId.
8609     * @param userId The userId in which the uri is to be resolved.
8610     */
8611    @Override
8612    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8613        synchronized(this) {
8614            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8615            if (owner == null) {
8616                throw new IllegalArgumentException("Unknown owner: " + token);
8617            }
8618
8619            if (uri == null) {
8620                owner.removeUriPermissionsLocked(mode);
8621            } else {
8622                final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
8623                owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
8624            }
8625        }
8626    }
8627
8628    private void schedulePersistUriGrants() {
8629        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8630            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8631                    10 * DateUtils.SECOND_IN_MILLIS);
8632        }
8633    }
8634
8635    private void writeGrantedUriPermissions() {
8636        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8637
8638        // Snapshot permissions so we can persist without lock
8639        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8640        synchronized (this) {
8641            final int size = mGrantedUriPermissions.size();
8642            for (int i = 0; i < size; i++) {
8643                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8644                for (UriPermission perm : perms.values()) {
8645                    if (perm.persistedModeFlags != 0) {
8646                        persist.add(perm.snapshot());
8647                    }
8648                }
8649            }
8650        }
8651
8652        FileOutputStream fos = null;
8653        try {
8654            fos = mGrantFile.startWrite();
8655
8656            XmlSerializer out = new FastXmlSerializer();
8657            out.setOutput(fos, StandardCharsets.UTF_8.name());
8658            out.startDocument(null, true);
8659            out.startTag(null, TAG_URI_GRANTS);
8660            for (UriPermission.Snapshot perm : persist) {
8661                out.startTag(null, TAG_URI_GRANT);
8662                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8663                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8664                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8665                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8666                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8667                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8668                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8669                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8670                out.endTag(null, TAG_URI_GRANT);
8671            }
8672            out.endTag(null, TAG_URI_GRANTS);
8673            out.endDocument();
8674
8675            mGrantFile.finishWrite(fos);
8676        } catch (IOException e) {
8677            if (fos != null) {
8678                mGrantFile.failWrite(fos);
8679            }
8680        }
8681    }
8682
8683    private void readGrantedUriPermissionsLocked() {
8684        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8685
8686        final long now = System.currentTimeMillis();
8687
8688        FileInputStream fis = null;
8689        try {
8690            fis = mGrantFile.openRead();
8691            final XmlPullParser in = Xml.newPullParser();
8692            in.setInput(fis, StandardCharsets.UTF_8.name());
8693
8694            int type;
8695            while ((type = in.next()) != END_DOCUMENT) {
8696                final String tag = in.getName();
8697                if (type == START_TAG) {
8698                    if (TAG_URI_GRANT.equals(tag)) {
8699                        final int sourceUserId;
8700                        final int targetUserId;
8701                        final int userHandle = readIntAttribute(in,
8702                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8703                        if (userHandle != UserHandle.USER_NULL) {
8704                            // For backwards compatibility.
8705                            sourceUserId = userHandle;
8706                            targetUserId = userHandle;
8707                        } else {
8708                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8709                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8710                        }
8711                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8712                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8713                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8714                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8715                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8716                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8717
8718                        // Sanity check that provider still belongs to source package
8719                        // Both direct boot aware and unaware packages are fine as we
8720                        // will do filtering at query time to avoid multiple parsing.
8721                        final ProviderInfo pi = getProviderInfoLocked(
8722                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
8723                                        | MATCH_DIRECT_BOOT_UNAWARE);
8724                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8725                            int targetUid = -1;
8726                            try {
8727                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8728                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8729                            } catch (RemoteException e) {
8730                            }
8731                            if (targetUid != -1) {
8732                                final UriPermission perm = findOrCreateUriPermissionLocked(
8733                                        sourcePkg, targetPkg, targetUid,
8734                                        new GrantUri(sourceUserId, uri, prefix));
8735                                perm.initPersistedModes(modeFlags, createdTime);
8736                            }
8737                        } else {
8738                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8739                                    + " but instead found " + pi);
8740                        }
8741                    }
8742                }
8743            }
8744        } catch (FileNotFoundException e) {
8745            // Missing grants is okay
8746        } catch (IOException e) {
8747            Slog.wtf(TAG, "Failed reading Uri grants", e);
8748        } catch (XmlPullParserException e) {
8749            Slog.wtf(TAG, "Failed reading Uri grants", e);
8750        } finally {
8751            IoUtils.closeQuietly(fis);
8752        }
8753    }
8754
8755    /**
8756     * @param uri This uri must NOT contain an embedded userId.
8757     * @param userId The userId in which the uri is to be resolved.
8758     */
8759    @Override
8760    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8761        enforceNotIsolatedCaller("takePersistableUriPermission");
8762
8763        Preconditions.checkFlagsArgument(modeFlags,
8764                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8765
8766        synchronized (this) {
8767            final int callingUid = Binder.getCallingUid();
8768            boolean persistChanged = false;
8769            GrantUri grantUri = new GrantUri(userId, uri, false);
8770
8771            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8772                    new GrantUri(userId, uri, false));
8773            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8774                    new GrantUri(userId, uri, true));
8775
8776            final boolean exactValid = (exactPerm != null)
8777                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8778            final boolean prefixValid = (prefixPerm != null)
8779                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8780
8781            if (!(exactValid || prefixValid)) {
8782                throw new SecurityException("No persistable permission grants found for UID "
8783                        + callingUid + " and Uri " + grantUri.toSafeString());
8784            }
8785
8786            if (exactValid) {
8787                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8788            }
8789            if (prefixValid) {
8790                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8791            }
8792
8793            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8794
8795            if (persistChanged) {
8796                schedulePersistUriGrants();
8797            }
8798        }
8799    }
8800
8801    /**
8802     * @param uri This uri must NOT contain an embedded userId.
8803     * @param userId The userId in which the uri is to be resolved.
8804     */
8805    @Override
8806    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8807        enforceNotIsolatedCaller("releasePersistableUriPermission");
8808
8809        Preconditions.checkFlagsArgument(modeFlags,
8810                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8811
8812        synchronized (this) {
8813            final int callingUid = Binder.getCallingUid();
8814            boolean persistChanged = false;
8815
8816            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8817                    new GrantUri(userId, uri, false));
8818            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8819                    new GrantUri(userId, uri, true));
8820            if (exactPerm == null && prefixPerm == null) {
8821                throw new SecurityException("No permission grants found for UID " + callingUid
8822                        + " and Uri " + uri.toSafeString());
8823            }
8824
8825            if (exactPerm != null) {
8826                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8827                removeUriPermissionIfNeededLocked(exactPerm);
8828            }
8829            if (prefixPerm != null) {
8830                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8831                removeUriPermissionIfNeededLocked(prefixPerm);
8832            }
8833
8834            if (persistChanged) {
8835                schedulePersistUriGrants();
8836            }
8837        }
8838    }
8839
8840    /**
8841     * Prune any older {@link UriPermission} for the given UID until outstanding
8842     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8843     *
8844     * @return if any mutations occured that require persisting.
8845     */
8846    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8847        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8848        if (perms == null) return false;
8849        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8850
8851        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8852        for (UriPermission perm : perms.values()) {
8853            if (perm.persistedModeFlags != 0) {
8854                persisted.add(perm);
8855            }
8856        }
8857
8858        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8859        if (trimCount <= 0) return false;
8860
8861        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8862        for (int i = 0; i < trimCount; i++) {
8863            final UriPermission perm = persisted.get(i);
8864
8865            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8866                    "Trimming grant created at " + perm.persistedCreateTime);
8867
8868            perm.releasePersistableModes(~0);
8869            removeUriPermissionIfNeededLocked(perm);
8870        }
8871
8872        return true;
8873    }
8874
8875    @Override
8876    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8877            String packageName, boolean incoming) {
8878        enforceNotIsolatedCaller("getPersistedUriPermissions");
8879        Preconditions.checkNotNull(packageName, "packageName");
8880
8881        final int callingUid = Binder.getCallingUid();
8882        final int callingUserId = UserHandle.getUserId(callingUid);
8883        final IPackageManager pm = AppGlobals.getPackageManager();
8884        try {
8885            final int packageUid = pm.getPackageUid(packageName,
8886                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
8887            if (packageUid != callingUid) {
8888                throw new SecurityException(
8889                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8890            }
8891        } catch (RemoteException e) {
8892            throw new SecurityException("Failed to verify package name ownership");
8893        }
8894
8895        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8896        synchronized (this) {
8897            if (incoming) {
8898                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8899                        callingUid);
8900                if (perms == null) {
8901                    Slog.w(TAG, "No permission grants found for " + packageName);
8902                } else {
8903                    for (UriPermission perm : perms.values()) {
8904                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8905                            result.add(perm.buildPersistedPublicApiObject());
8906                        }
8907                    }
8908                }
8909            } else {
8910                final int size = mGrantedUriPermissions.size();
8911                for (int i = 0; i < size; i++) {
8912                    final ArrayMap<GrantUri, UriPermission> perms =
8913                            mGrantedUriPermissions.valueAt(i);
8914                    for (UriPermission perm : perms.values()) {
8915                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8916                            result.add(perm.buildPersistedPublicApiObject());
8917                        }
8918                    }
8919                }
8920            }
8921        }
8922        return new ParceledListSlice<android.content.UriPermission>(result);
8923    }
8924
8925    @Override
8926    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8927            String packageName, int userId) {
8928        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8929                "getGrantedUriPermissions");
8930
8931        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8932        synchronized (this) {
8933            final int size = mGrantedUriPermissions.size();
8934            for (int i = 0; i < size; i++) {
8935                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8936                for (UriPermission perm : perms.values()) {
8937                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8938                            && perm.persistedModeFlags != 0) {
8939                        result.add(perm.buildPersistedPublicApiObject());
8940                    }
8941                }
8942            }
8943        }
8944        return new ParceledListSlice<android.content.UriPermission>(result);
8945    }
8946
8947    @Override
8948    public void clearGrantedUriPermissions(String packageName, int userId) {
8949        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8950                "clearGrantedUriPermissions");
8951        removeUriPermissionsForPackageLocked(packageName, userId, true);
8952    }
8953
8954    @Override
8955    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8956        synchronized (this) {
8957            ProcessRecord app =
8958                who != null ? getRecordForAppLocked(who) : null;
8959            if (app == null) return;
8960
8961            Message msg = Message.obtain();
8962            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8963            msg.obj = app;
8964            msg.arg1 = waiting ? 1 : 0;
8965            mUiHandler.sendMessage(msg);
8966        }
8967    }
8968
8969    @Override
8970    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8971        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8972        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8973        outInfo.availMem = Process.getFreeMemory();
8974        outInfo.totalMem = Process.getTotalMemory();
8975        outInfo.threshold = homeAppMem;
8976        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8977        outInfo.hiddenAppThreshold = cachedAppMem;
8978        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8979                ProcessList.SERVICE_ADJ);
8980        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8981                ProcessList.VISIBLE_APP_ADJ);
8982        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8983                ProcessList.FOREGROUND_APP_ADJ);
8984    }
8985
8986    // =========================================================
8987    // TASK MANAGEMENT
8988    // =========================================================
8989
8990    @Override
8991    public List<IAppTask> getAppTasks(String callingPackage) {
8992        int callingUid = Binder.getCallingUid();
8993        long ident = Binder.clearCallingIdentity();
8994
8995        synchronized(this) {
8996            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8997            try {
8998                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8999
9000                final int N = mRecentTasks.size();
9001                for (int i = 0; i < N; i++) {
9002                    TaskRecord tr = mRecentTasks.get(i);
9003                    // Skip tasks that do not match the caller.  We don't need to verify
9004                    // callingPackage, because we are also limiting to callingUid and know
9005                    // that will limit to the correct security sandbox.
9006                    if (tr.effectiveUid != callingUid) {
9007                        continue;
9008                    }
9009                    Intent intent = tr.getBaseIntent();
9010                    if (intent == null ||
9011                            !callingPackage.equals(intent.getComponent().getPackageName())) {
9012                        continue;
9013                    }
9014                    ActivityManager.RecentTaskInfo taskInfo =
9015                            createRecentTaskInfoFromTaskRecord(tr);
9016                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9017                    list.add(taskImpl);
9018                }
9019            } finally {
9020                Binder.restoreCallingIdentity(ident);
9021            }
9022            return list;
9023        }
9024    }
9025
9026    @Override
9027    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9028        final int callingUid = Binder.getCallingUid();
9029        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9030
9031        synchronized(this) {
9032            if (DEBUG_ALL) Slog.v(
9033                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9034
9035            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9036                    callingUid);
9037
9038            // TODO: Improve with MRU list from all ActivityStacks.
9039            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9040        }
9041
9042        return list;
9043    }
9044
9045    /**
9046     * Creates a new RecentTaskInfo from a TaskRecord.
9047     */
9048    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9049        // Update the task description to reflect any changes in the task stack
9050        tr.updateTaskDescription();
9051
9052        // Compose the recent task info
9053        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9054        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9055        rti.persistentId = tr.taskId;
9056        rti.baseIntent = new Intent(tr.getBaseIntent());
9057        rti.origActivity = tr.origActivity;
9058        rti.realActivity = tr.realActivity;
9059        rti.description = tr.lastDescription;
9060        rti.stackId = tr.getStackId();
9061        rti.userId = tr.userId;
9062        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9063        rti.firstActiveTime = tr.firstActiveTime;
9064        rti.lastActiveTime = tr.lastActiveTime;
9065        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9066        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9067        rti.numActivities = 0;
9068        if (tr.mBounds != null) {
9069            rti.bounds = new Rect(tr.mBounds);
9070        }
9071        rti.isDockable = tr.canGoInDockedStack();
9072        rti.resizeMode = tr.mResizeMode;
9073
9074        ActivityRecord base = null;
9075        ActivityRecord top = null;
9076        ActivityRecord tmp;
9077
9078        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9079            tmp = tr.mActivities.get(i);
9080            if (tmp.finishing) {
9081                continue;
9082            }
9083            base = tmp;
9084            if (top == null || (top.state == ActivityState.INITIALIZING)) {
9085                top = base;
9086            }
9087            rti.numActivities++;
9088        }
9089
9090        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9091        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9092
9093        return rti;
9094    }
9095
9096    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9097        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9098                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9099        if (!allowed) {
9100            if (checkPermission(android.Manifest.permission.GET_TASKS,
9101                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9102                // Temporary compatibility: some existing apps on the system image may
9103                // still be requesting the old permission and not switched to the new
9104                // one; if so, we'll still allow them full access.  This means we need
9105                // to see if they are holding the old permission and are a system app.
9106                try {
9107                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9108                        allowed = true;
9109                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9110                                + " is using old GET_TASKS but privileged; allowing");
9111                    }
9112                } catch (RemoteException e) {
9113                }
9114            }
9115        }
9116        if (!allowed) {
9117            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9118                    + " does not hold REAL_GET_TASKS; limiting output");
9119        }
9120        return allowed;
9121    }
9122
9123    @Override
9124    public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9125            int userId) {
9126        final int callingUid = Binder.getCallingUid();
9127        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9128                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9129
9130        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9131        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9132        synchronized (this) {
9133            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9134                    callingUid);
9135            final boolean detailed = checkCallingPermission(
9136                    android.Manifest.permission.GET_DETAILED_TASKS)
9137                    == PackageManager.PERMISSION_GRANTED;
9138
9139            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9140                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9141                return ParceledListSlice.emptyList();
9142            }
9143            mRecentTasks.loadUserRecentsLocked(userId);
9144
9145            final int recentsCount = mRecentTasks.size();
9146            ArrayList<ActivityManager.RecentTaskInfo> res =
9147                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9148
9149            final Set<Integer> includedUsers;
9150            if (includeProfiles) {
9151                includedUsers = mUserController.getProfileIds(userId);
9152            } else {
9153                includedUsers = new HashSet<>();
9154            }
9155            includedUsers.add(Integer.valueOf(userId));
9156
9157            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9158                TaskRecord tr = mRecentTasks.get(i);
9159                // Only add calling user or related users recent tasks
9160                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9161                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9162                    continue;
9163                }
9164
9165                if (tr.realActivitySuspended) {
9166                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9167                    continue;
9168                }
9169
9170                // Return the entry if desired by the caller.  We always return
9171                // the first entry, because callers always expect this to be the
9172                // foreground app.  We may filter others if the caller has
9173                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9174                // we should exclude the entry.
9175
9176                if (i == 0
9177                        || withExcluded
9178                        || (tr.intent == null)
9179                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9180                                == 0)) {
9181                    if (!allowed) {
9182                        // If the caller doesn't have the GET_TASKS permission, then only
9183                        // allow them to see a small subset of tasks -- their own and home.
9184                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9185                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9186                            continue;
9187                        }
9188                    }
9189                    final ActivityStack stack = tr.getStack();
9190                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9191                        if (stack != null && stack.isHomeStack()) {
9192                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9193                                    "Skipping, home stack task: " + tr);
9194                            continue;
9195                        }
9196                    }
9197                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9198                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9199                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9200                                    "Skipping, top task in docked stack: " + tr);
9201                            continue;
9202                        }
9203                    }
9204                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9205                        if (stack != null && stack.isPinnedStack()) {
9206                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9207                                    "Skipping, pinned stack task: " + tr);
9208                            continue;
9209                        }
9210                    }
9211                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9212                        // Don't include auto remove tasks that are finished or finishing.
9213                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9214                                "Skipping, auto-remove without activity: " + tr);
9215                        continue;
9216                    }
9217                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9218                            && !tr.isAvailable) {
9219                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9220                                "Skipping, unavail real act: " + tr);
9221                        continue;
9222                    }
9223
9224                    if (!tr.mUserSetupComplete) {
9225                        // Don't include task launched while user is not done setting-up.
9226                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9227                                "Skipping, user setup not complete: " + tr);
9228                        continue;
9229                    }
9230
9231                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9232                    if (!detailed) {
9233                        rti.baseIntent.replaceExtras((Bundle)null);
9234                    }
9235
9236                    res.add(rti);
9237                    maxNum--;
9238                }
9239            }
9240            return new ParceledListSlice<>(res);
9241        }
9242    }
9243
9244    @Override
9245    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9246        synchronized (this) {
9247            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9248                    "getTaskThumbnail()");
9249            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9250                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9251            if (tr != null) {
9252                return tr.getTaskThumbnailLocked();
9253            }
9254        }
9255        return null;
9256    }
9257
9258    @Override
9259    public int addAppTask(IBinder activityToken, Intent intent,
9260            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9261        final int callingUid = Binder.getCallingUid();
9262        final long callingIdent = Binder.clearCallingIdentity();
9263
9264        try {
9265            synchronized (this) {
9266                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9267                if (r == null) {
9268                    throw new IllegalArgumentException("Activity does not exist; token="
9269                            + activityToken);
9270                }
9271                ComponentName comp = intent.getComponent();
9272                if (comp == null) {
9273                    throw new IllegalArgumentException("Intent " + intent
9274                            + " must specify explicit component");
9275                }
9276                if (thumbnail.getWidth() != mThumbnailWidth
9277                        || thumbnail.getHeight() != mThumbnailHeight) {
9278                    throw new IllegalArgumentException("Bad thumbnail size: got "
9279                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9280                            + mThumbnailWidth + "x" + mThumbnailHeight);
9281                }
9282                if (intent.getSelector() != null) {
9283                    intent.setSelector(null);
9284                }
9285                if (intent.getSourceBounds() != null) {
9286                    intent.setSourceBounds(null);
9287                }
9288                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9289                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9290                        // The caller has added this as an auto-remove task...  that makes no
9291                        // sense, so turn off auto-remove.
9292                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9293                    }
9294                }
9295                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9296                    mLastAddedTaskActivity = null;
9297                }
9298                ActivityInfo ainfo = mLastAddedTaskActivity;
9299                if (ainfo == null) {
9300                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9301                            comp, 0, UserHandle.getUserId(callingUid));
9302                    if (ainfo.applicationInfo.uid != callingUid) {
9303                        throw new SecurityException(
9304                                "Can't add task for another application: target uid="
9305                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9306                    }
9307                }
9308
9309                TaskRecord task = new TaskRecord(this,
9310                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9311                        ainfo, intent, description, new TaskThumbnailInfo());
9312
9313                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9314                if (trimIdx >= 0) {
9315                    // If this would have caused a trim, then we'll abort because that
9316                    // means it would be added at the end of the list but then just removed.
9317                    return INVALID_TASK_ID;
9318                }
9319
9320                final int N = mRecentTasks.size();
9321                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9322                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9323                    tr.removedFromRecents();
9324                }
9325
9326                task.inRecents = true;
9327                mRecentTasks.add(task);
9328                r.getStack().addTask(task, false, "addAppTask");
9329
9330                task.setLastThumbnailLocked(thumbnail);
9331                task.freeLastThumbnail();
9332                return task.taskId;
9333            }
9334        } finally {
9335            Binder.restoreCallingIdentity(callingIdent);
9336        }
9337    }
9338
9339    @Override
9340    public Point getAppTaskThumbnailSize() {
9341        synchronized (this) {
9342            return new Point(mThumbnailWidth,  mThumbnailHeight);
9343        }
9344    }
9345
9346    @Override
9347    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9348        synchronized (this) {
9349            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9350            if (r != null) {
9351                r.setTaskDescription(td);
9352                r.task.updateTaskDescription();
9353                mTaskChangeNotificationController.notifyTaskDescriptionChanged(r.task.taskId, td);
9354            }
9355        }
9356    }
9357
9358    @Override
9359    public void setTaskResizeable(int taskId, int resizeableMode) {
9360        synchronized (this) {
9361            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9362                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9363            if (task == null) {
9364                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9365                return;
9366            }
9367            if (task.mResizeMode != resizeableMode) {
9368                task.mResizeMode = resizeableMode;
9369                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9370                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9371                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9372            }
9373        }
9374    }
9375
9376    @Override
9377    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9378        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9379        long ident = Binder.clearCallingIdentity();
9380        try {
9381            synchronized (this) {
9382                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9383                if (task == null) {
9384                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9385                    return;
9386                }
9387                // Place the task in the right stack if it isn't there already based on
9388                // the requested bounds.
9389                // The stack transition logic is:
9390                // - a null bounds on a freeform task moves that task to fullscreen
9391                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9392                //   that task to freeform
9393                // - otherwise the task is not moved
9394                int stackId = task.getStackId();
9395                if (!StackId.isTaskResizeAllowed(stackId)) {
9396                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9397                }
9398                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9399                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9400                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9401                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9402                }
9403                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9404                if (stackId != task.getStackId()) {
9405                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9406                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9407                    preserveWindow = false;
9408                }
9409
9410                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9411                        false /* deferResume */);
9412            }
9413        } finally {
9414            Binder.restoreCallingIdentity(ident);
9415        }
9416    }
9417
9418    @Override
9419    public Rect getTaskBounds(int taskId) {
9420        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9421        long ident = Binder.clearCallingIdentity();
9422        Rect rect = new Rect();
9423        try {
9424            synchronized (this) {
9425                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9426                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9427                if (task == null) {
9428                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9429                    return rect;
9430                }
9431                if (task.getStack() != null) {
9432                    // Return the bounds from window manager since it will be adjusted for various
9433                    // things like the presense of a docked stack for tasks that aren't resizeable.
9434                    mWindowManager.getTaskBounds(task.taskId, rect);
9435                } else {
9436                    // Task isn't in window manager yet since it isn't associated with a stack.
9437                    // Return the persist value from activity manager
9438                    if (task.mBounds != null) {
9439                        rect.set(task.mBounds);
9440                    } else if (task.mLastNonFullscreenBounds != null) {
9441                        rect.set(task.mLastNonFullscreenBounds);
9442                    }
9443                }
9444            }
9445        } finally {
9446            Binder.restoreCallingIdentity(ident);
9447        }
9448        return rect;
9449    }
9450
9451    @Override
9452    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9453        if (userId != UserHandle.getCallingUserId()) {
9454            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9455                    "getTaskDescriptionIcon");
9456        }
9457        final File passedIconFile = new File(filePath);
9458        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9459                passedIconFile.getName());
9460        if (!legitIconFile.getPath().equals(filePath)
9461                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9462            throw new IllegalArgumentException("Bad file path: " + filePath
9463                    + " passed for userId " + userId);
9464        }
9465        return mRecentTasks.getTaskDescriptionIcon(filePath);
9466    }
9467
9468    @Override
9469    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9470            throws RemoteException {
9471        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9472                opts.getCustomInPlaceResId() == 0) {
9473            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9474                    "with valid animation");
9475        }
9476        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9477        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9478                opts.getCustomInPlaceResId());
9479        mWindowManager.executeAppTransition();
9480    }
9481
9482    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9483            boolean removeFromRecents) {
9484        if (removeFromRecents) {
9485            mRecentTasks.remove(tr);
9486            tr.removedFromRecents();
9487        }
9488        ComponentName component = tr.getBaseIntent().getComponent();
9489        if (component == null) {
9490            Slog.w(TAG, "No component for base intent of task: " + tr);
9491            return;
9492        }
9493
9494        // Find any running services associated with this app and stop if needed.
9495        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9496
9497        if (!killProcess) {
9498            return;
9499        }
9500
9501        // Determine if the process(es) for this task should be killed.
9502        final String pkg = component.getPackageName();
9503        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9504        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9505        for (int i = 0; i < pmap.size(); i++) {
9506
9507            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9508            for (int j = 0; j < uids.size(); j++) {
9509                ProcessRecord proc = uids.valueAt(j);
9510                if (proc.userId != tr.userId) {
9511                    // Don't kill process for a different user.
9512                    continue;
9513                }
9514                if (proc == mHomeProcess) {
9515                    // Don't kill the home process along with tasks from the same package.
9516                    continue;
9517                }
9518                if (!proc.pkgList.containsKey(pkg)) {
9519                    // Don't kill process that is not associated with this task.
9520                    continue;
9521                }
9522
9523                for (int k = 0; k < proc.activities.size(); k++) {
9524                    TaskRecord otherTask = proc.activities.get(k).task;
9525                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9526                        // Don't kill process(es) that has an activity in a different task that is
9527                        // also in recents.
9528                        return;
9529                    }
9530                }
9531
9532                if (proc.foregroundServices) {
9533                    // Don't kill process(es) with foreground service.
9534                    return;
9535                }
9536
9537                // Add process to kill list.
9538                procsToKill.add(proc);
9539            }
9540        }
9541
9542        // Kill the running processes.
9543        for (int i = 0; i < procsToKill.size(); i++) {
9544            ProcessRecord pr = procsToKill.get(i);
9545            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9546                    && pr.curReceivers.isEmpty()) {
9547                pr.kill("remove task", true);
9548            } else {
9549                // We delay killing processes that are not in the background or running a receiver.
9550                pr.waitingToKill = "remove task";
9551            }
9552        }
9553    }
9554
9555    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9556        // Remove all tasks with activities in the specified package from the list of recent tasks
9557        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9558            TaskRecord tr = mRecentTasks.get(i);
9559            if (tr.userId != userId) continue;
9560
9561            ComponentName cn = tr.intent.getComponent();
9562            if (cn != null && cn.getPackageName().equals(packageName)) {
9563                // If the package name matches, remove the task.
9564                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9565            }
9566        }
9567    }
9568
9569    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9570            int userId) {
9571
9572        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9573            TaskRecord tr = mRecentTasks.get(i);
9574            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9575                continue;
9576            }
9577
9578            ComponentName cn = tr.intent.getComponent();
9579            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9580                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9581            if (sameComponent) {
9582                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9583            }
9584        }
9585    }
9586
9587    /**
9588     * Removes the task with the specified task id.
9589     *
9590     * @param taskId Identifier of the task to be removed.
9591     * @param killProcess Kill any process associated with the task if possible.
9592     * @param removeFromRecents Whether to also remove the task from recents.
9593     * @return Returns true if the given task was found and removed.
9594     */
9595    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9596            boolean removeFromRecents) {
9597        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9598                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9599        if (tr != null) {
9600            tr.removeTaskActivitiesLocked();
9601            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9602            if (tr.isPersistable) {
9603                notifyTaskPersisterLocked(null, true);
9604            }
9605            return true;
9606        }
9607        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9608        return false;
9609    }
9610
9611    @Override
9612    public void removeStack(int stackId) {
9613        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9614        if (stackId == HOME_STACK_ID) {
9615            throw new IllegalArgumentException("Removing home stack is not allowed.");
9616        }
9617
9618        synchronized (this) {
9619            final long ident = Binder.clearCallingIdentity();
9620            try {
9621                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9622                if (stack == null) {
9623                    return;
9624                }
9625                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9626                for (int i = tasks.size() - 1; i >= 0; i--) {
9627                    removeTaskByIdLocked(
9628                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9629                }
9630            } finally {
9631                Binder.restoreCallingIdentity(ident);
9632            }
9633        }
9634    }
9635
9636    @Override
9637    public boolean removeTask(int taskId) {
9638        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9639        synchronized (this) {
9640            final long ident = Binder.clearCallingIdentity();
9641            try {
9642                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9643            } finally {
9644                Binder.restoreCallingIdentity(ident);
9645            }
9646        }
9647    }
9648
9649    /**
9650     * TODO: Add mController hook
9651     */
9652    @Override
9653    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9654        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9655
9656        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9657        synchronized(this) {
9658            moveTaskToFrontLocked(taskId, flags, bOptions);
9659        }
9660    }
9661
9662    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9663        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9664
9665        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9666                Binder.getCallingUid(), -1, -1, "Task to front")) {
9667            ActivityOptions.abort(options);
9668            return;
9669        }
9670        final long origId = Binder.clearCallingIdentity();
9671        try {
9672            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9673            if (task == null) {
9674                Slog.d(TAG, "Could not find task for id: "+ taskId);
9675                return;
9676            }
9677            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9678                mStackSupervisor.showLockTaskToast();
9679                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9680                return;
9681            }
9682            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9683            if (prev != null && prev.isRecentsActivity()) {
9684                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9685            }
9686            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9687                    false /* forceNonResizable */);
9688        } finally {
9689            Binder.restoreCallingIdentity(origId);
9690        }
9691        ActivityOptions.abort(options);
9692    }
9693
9694    /**
9695     * Moves an activity, and all of the other activities within the same task, to the bottom
9696     * of the history stack.  The activity's order within the task is unchanged.
9697     *
9698     * @param token A reference to the activity we wish to move
9699     * @param nonRoot If false then this only works if the activity is the root
9700     *                of a task; if true it will work for any activity in a task.
9701     * @return Returns true if the move completed, false if not.
9702     */
9703    @Override
9704    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9705        enforceNotIsolatedCaller("moveActivityTaskToBack");
9706        synchronized(this) {
9707            final long origId = Binder.clearCallingIdentity();
9708            try {
9709                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9710                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9711                if (task != null) {
9712                    if (mStackSupervisor.isLockedTask(task)) {
9713                        mStackSupervisor.showLockTaskToast();
9714                        return false;
9715                    }
9716                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9717                }
9718            } finally {
9719                Binder.restoreCallingIdentity(origId);
9720            }
9721        }
9722        return false;
9723    }
9724
9725    @Override
9726    public void moveTaskBackwards(int task) {
9727        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9728                "moveTaskBackwards()");
9729
9730        synchronized(this) {
9731            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9732                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9733                return;
9734            }
9735            final long origId = Binder.clearCallingIdentity();
9736            moveTaskBackwardsLocked(task);
9737            Binder.restoreCallingIdentity(origId);
9738        }
9739    }
9740
9741    private final void moveTaskBackwardsLocked(int task) {
9742        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9743    }
9744
9745    @Override
9746    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9747            IActivityContainerCallback callback) throws RemoteException {
9748        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9749        synchronized (this) {
9750            if (parentActivityToken == null) {
9751                throw new IllegalArgumentException("parent token must not be null");
9752            }
9753            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9754            if (r == null) {
9755                return null;
9756            }
9757            if (callback == null) {
9758                throw new IllegalArgumentException("callback must not be null");
9759            }
9760            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9761        }
9762    }
9763
9764    @Override
9765    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9766        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9767        synchronized (this) {
9768            final int stackId = mStackSupervisor.getNextStackId();
9769            final ActivityStack stack =
9770                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9771            if (stack == null) {
9772                return null;
9773            }
9774            return stack.mActivityContainer;
9775        }
9776    }
9777
9778    @Override
9779    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9780        synchronized (this) {
9781            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9782            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9783                return stack.mActivityContainer.getDisplayId();
9784            }
9785            return DEFAULT_DISPLAY;
9786        }
9787    }
9788
9789    @Override
9790    public int getActivityStackId(IBinder token) throws RemoteException {
9791        synchronized (this) {
9792            ActivityStack stack = ActivityRecord.getStackLocked(token);
9793            if (stack == null) {
9794                return INVALID_STACK_ID;
9795            }
9796            return stack.mStackId;
9797        }
9798    }
9799
9800    @Override
9801    public void exitFreeformMode(IBinder token) throws RemoteException {
9802        synchronized (this) {
9803            long ident = Binder.clearCallingIdentity();
9804            try {
9805                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9806                if (r == null) {
9807                    throw new IllegalArgumentException(
9808                            "exitFreeformMode: No activity record matching token=" + token);
9809                }
9810                final ActivityStack stack = r.getStackLocked(token);
9811                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9812                    throw new IllegalStateException(
9813                            "exitFreeformMode: You can only go fullscreen from freeform.");
9814                }
9815                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9816                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9817                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9818            } finally {
9819                Binder.restoreCallingIdentity(ident);
9820            }
9821        }
9822    }
9823
9824    @Override
9825    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9826        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9827        if (stackId == HOME_STACK_ID) {
9828            throw new IllegalArgumentException(
9829                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9830        }
9831        synchronized (this) {
9832            long ident = Binder.clearCallingIdentity();
9833            try {
9834                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9835                        + " to stackId=" + stackId + " toTop=" + toTop);
9836                if (stackId == DOCKED_STACK_ID) {
9837                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9838                            null /* initialBounds */);
9839                }
9840                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9841                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9842                if (result && stackId == DOCKED_STACK_ID) {
9843                    // If task moved to docked stack - show recents if needed.
9844                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9845                            "moveTaskToDockedStack");
9846                }
9847            } finally {
9848                Binder.restoreCallingIdentity(ident);
9849            }
9850        }
9851    }
9852
9853    @Override
9854    public void swapDockedAndFullscreenStack() throws RemoteException {
9855        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9856        synchronized (this) {
9857            long ident = Binder.clearCallingIdentity();
9858            try {
9859                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9860                        FULLSCREEN_WORKSPACE_STACK_ID);
9861                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9862                        : null;
9863                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9864                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9865                        : null;
9866                if (topTask == null || tasks == null || tasks.size() == 0) {
9867                    Slog.w(TAG,
9868                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9869                    return;
9870                }
9871
9872                // TODO: App transition
9873                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9874
9875                // Defer the resume so resume/pausing while moving stacks is dangerous.
9876                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9877                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9878                        ANIMATE, true /* deferResume */);
9879                final int size = tasks.size();
9880                for (int i = 0; i < size; i++) {
9881                    final int id = tasks.get(i).taskId;
9882                    if (id == topTask.taskId) {
9883                        continue;
9884                    }
9885                    mStackSupervisor.moveTaskToStackLocked(id,
9886                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9887                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9888                }
9889
9890                // Because we deferred the resume, to avoid conflicts with stack switches while
9891                // resuming, we need to do it after all the tasks are moved.
9892                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9893                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9894
9895                mWindowManager.executeAppTransition();
9896            } finally {
9897                Binder.restoreCallingIdentity(ident);
9898            }
9899        }
9900    }
9901
9902    /**
9903     * Moves the input task to the docked stack.
9904     *
9905     * @param taskId Id of task to move.
9906     * @param createMode The mode the docked stack should be created in if it doesn't exist
9907     *                   already. See
9908     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9909     *                   and
9910     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9911     * @param toTop If the task and stack should be moved to the top.
9912     * @param animate Whether we should play an animation for the moving the task
9913     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9914     *                      docked stack. Pass {@code null} to use default bounds.
9915     */
9916    @Override
9917    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9918            Rect initialBounds, boolean moveHomeStackFront) {
9919        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9920        synchronized (this) {
9921            long ident = Binder.clearCallingIdentity();
9922            try {
9923                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9924                        + " to createMode=" + createMode + " toTop=" + toTop);
9925                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9926                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9927                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9928                        animate, DEFER_RESUME);
9929                if (moved) {
9930                    if (moveHomeStackFront) {
9931                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9932                    }
9933                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9934                }
9935                return moved;
9936            } finally {
9937                Binder.restoreCallingIdentity(ident);
9938            }
9939        }
9940    }
9941
9942    /**
9943     * Moves the top activity in the input stackId to the pinned stack.
9944     *
9945     * @param stackId Id of stack to move the top activity to pinned stack.
9946     * @param bounds Bounds to use for pinned stack.
9947     *
9948     * @return True if the top activity of the input stack was successfully moved to the pinned
9949     *          stack.
9950     */
9951    @Override
9952    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9953        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9954        synchronized (this) {
9955            if (!mSupportsPictureInPicture) {
9956                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9957                        + "Device doesn't support picture-in-pciture mode");
9958            }
9959
9960            long ident = Binder.clearCallingIdentity();
9961            try {
9962                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9963            } finally {
9964                Binder.restoreCallingIdentity(ident);
9965            }
9966        }
9967    }
9968
9969    @Override
9970    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9971            boolean preserveWindows, boolean animate, int animationDuration) {
9972        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9973        long ident = Binder.clearCallingIdentity();
9974        try {
9975            synchronized (this) {
9976                if (animate) {
9977                    if (stackId == PINNED_STACK_ID) {
9978                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9979                    } else {
9980                        throw new IllegalArgumentException("Stack: " + stackId
9981                                + " doesn't support animated resize.");
9982                    }
9983                } else {
9984                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9985                            null /* tempTaskInsetBounds */, preserveWindows,
9986                            allowResizeInDockedMode, !DEFER_RESUME);
9987                }
9988            }
9989        } finally {
9990            Binder.restoreCallingIdentity(ident);
9991        }
9992    }
9993
9994    @Override
9995    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9996            Rect tempDockedTaskInsetBounds,
9997            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9998        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9999                "resizeDockedStack()");
10000        long ident = Binder.clearCallingIdentity();
10001        try {
10002            synchronized (this) {
10003                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10004                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10005                        PRESERVE_WINDOWS);
10006            }
10007        } finally {
10008            Binder.restoreCallingIdentity(ident);
10009        }
10010    }
10011
10012    @Override
10013    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10014        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10015                "resizePinnedStack()");
10016        final long ident = Binder.clearCallingIdentity();
10017        try {
10018            synchronized (this) {
10019                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10020            }
10021        } finally {
10022            Binder.restoreCallingIdentity(ident);
10023        }
10024    }
10025
10026    @Override
10027    public void positionTaskInStack(int taskId, int stackId, int position) {
10028        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10029        if (stackId == HOME_STACK_ID) {
10030            throw new IllegalArgumentException(
10031                    "positionTaskInStack: Attempt to change the position of task "
10032                    + taskId + " in/to home stack");
10033        }
10034        synchronized (this) {
10035            long ident = Binder.clearCallingIdentity();
10036            try {
10037                if (DEBUG_STACK) Slog.d(TAG_STACK,
10038                        "positionTaskInStack: positioning task=" + taskId
10039                        + " in stackId=" + stackId + " at position=" + position);
10040                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
10041            } finally {
10042                Binder.restoreCallingIdentity(ident);
10043            }
10044        }
10045    }
10046
10047    @Override
10048    public List<StackInfo> getAllStackInfos() {
10049        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10050        long ident = Binder.clearCallingIdentity();
10051        try {
10052            synchronized (this) {
10053                return mStackSupervisor.getAllStackInfosLocked();
10054            }
10055        } finally {
10056            Binder.restoreCallingIdentity(ident);
10057        }
10058    }
10059
10060    @Override
10061    public StackInfo getStackInfo(int stackId) {
10062        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10063        long ident = Binder.clearCallingIdentity();
10064        try {
10065            synchronized (this) {
10066                return mStackSupervisor.getStackInfoLocked(stackId);
10067            }
10068        } finally {
10069            Binder.restoreCallingIdentity(ident);
10070        }
10071    }
10072
10073    @Override
10074    public boolean isInHomeStack(int taskId) {
10075        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10076        long ident = Binder.clearCallingIdentity();
10077        try {
10078            synchronized (this) {
10079                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10080                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
10081                final ActivityStack stack = tr != null ? tr.getStack() : null;
10082                return stack != null && stack.isHomeStack();
10083            }
10084        } finally {
10085            Binder.restoreCallingIdentity(ident);
10086        }
10087    }
10088
10089    @Override
10090    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10091        synchronized(this) {
10092            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10093        }
10094    }
10095
10096    @Override
10097    public void updateDeviceOwner(String packageName) {
10098        final int callingUid = Binder.getCallingUid();
10099        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10100            throw new SecurityException("updateDeviceOwner called from non-system process");
10101        }
10102        synchronized (this) {
10103            mDeviceOwnerName = packageName;
10104        }
10105    }
10106
10107    @Override
10108    public void updateLockTaskPackages(int userId, String[] packages) {
10109        final int callingUid = Binder.getCallingUid();
10110        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10111            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10112                    "updateLockTaskPackages()");
10113        }
10114        synchronized (this) {
10115            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10116                    Arrays.toString(packages));
10117            mLockTaskPackages.put(userId, packages);
10118            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10119        }
10120    }
10121
10122
10123    void startLockTaskModeLocked(TaskRecord task) {
10124        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10125        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10126            return;
10127        }
10128
10129        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10130        // is initiated by system after the pinning request was shown and locked mode is initiated
10131        // by an authorized app directly
10132        final int callingUid = Binder.getCallingUid();
10133        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10134        long ident = Binder.clearCallingIdentity();
10135        try {
10136            if (!isSystemInitiated) {
10137                task.mLockTaskUid = callingUid;
10138                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10139                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10140                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10141                    StatusBarManagerInternal statusBarManager =
10142                            LocalServices.getService(StatusBarManagerInternal.class);
10143                    if (statusBarManager != null) {
10144                        statusBarManager.showScreenPinningRequest(task.taskId);
10145                    }
10146                    return;
10147                }
10148
10149                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10150                if (stack == null || task != stack.topTask()) {
10151                    throw new IllegalArgumentException("Invalid task, not in foreground");
10152                }
10153            }
10154            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10155                    "Locking fully");
10156            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10157                    ActivityManager.LOCK_TASK_MODE_PINNED :
10158                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10159                    "startLockTask", true);
10160        } finally {
10161            Binder.restoreCallingIdentity(ident);
10162        }
10163    }
10164
10165    @Override
10166    public void startLockTaskMode(int taskId) {
10167        synchronized (this) {
10168            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10169            if (task != null) {
10170                startLockTaskModeLocked(task);
10171            }
10172        }
10173    }
10174
10175    @Override
10176    public void startLockTaskMode(IBinder token) {
10177        synchronized (this) {
10178            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10179            if (r == null) {
10180                return;
10181            }
10182            final TaskRecord task = r.task;
10183            if (task != null) {
10184                startLockTaskModeLocked(task);
10185            }
10186        }
10187    }
10188
10189    @Override
10190    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10191        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10192        // This makes inner call to look as if it was initiated by system.
10193        long ident = Binder.clearCallingIdentity();
10194        try {
10195            synchronized (this) {
10196                startLockTaskMode(taskId);
10197            }
10198        } finally {
10199            Binder.restoreCallingIdentity(ident);
10200        }
10201    }
10202
10203    @Override
10204    public void stopLockTaskMode() {
10205        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10206        if (lockTask == null) {
10207            // Our work here is done.
10208            return;
10209        }
10210
10211        final int callingUid = Binder.getCallingUid();
10212        final int lockTaskUid = lockTask.mLockTaskUid;
10213        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10214        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10215            // Done.
10216            return;
10217        } else {
10218            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10219            // It is possible lockTaskMode was started by the system process because
10220            // android:lockTaskMode is set to a locking value in the application manifest
10221            // instead of the app calling startLockTaskMode. In this case
10222            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10223            // {@link TaskRecord.effectiveUid} instead. Also caller with
10224            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10225            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10226                    && callingUid != lockTaskUid
10227                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10228                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10229                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10230            }
10231        }
10232        long ident = Binder.clearCallingIdentity();
10233        try {
10234            Log.d(TAG, "stopLockTaskMode");
10235            // Stop lock task
10236            synchronized (this) {
10237                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10238                        "stopLockTask", true);
10239            }
10240            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10241            if (tm != null) {
10242                tm.showInCallScreen(false);
10243            }
10244        } finally {
10245            Binder.restoreCallingIdentity(ident);
10246        }
10247    }
10248
10249    /**
10250     * This API should be called by SystemUI only when user perform certain action to dismiss
10251     * lock task mode. We should only dismiss pinned lock task mode in this case.
10252     */
10253    @Override
10254    public void stopSystemLockTaskMode() throws RemoteException {
10255        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10256            stopLockTaskMode();
10257        } else {
10258            mStackSupervisor.showLockTaskToast();
10259        }
10260    }
10261
10262    @Override
10263    public boolean isInLockTaskMode() {
10264        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10265    }
10266
10267    @Override
10268    public int getLockTaskModeState() {
10269        synchronized (this) {
10270            return mStackSupervisor.getLockTaskModeState();
10271        }
10272    }
10273
10274    @Override
10275    public void showLockTaskEscapeMessage(IBinder token) {
10276        synchronized (this) {
10277            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10278            if (r == null) {
10279                return;
10280            }
10281            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10282        }
10283    }
10284
10285    // =========================================================
10286    // CONTENT PROVIDERS
10287    // =========================================================
10288
10289    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10290        List<ProviderInfo> providers = null;
10291        try {
10292            providers = AppGlobals.getPackageManager()
10293                    .queryContentProviders(app.processName, app.uid,
10294                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10295                                    | MATCH_DEBUG_TRIAGED_MISSING)
10296                    .getList();
10297        } catch (RemoteException ex) {
10298        }
10299        if (DEBUG_MU) Slog.v(TAG_MU,
10300                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10301        int userId = app.userId;
10302        if (providers != null) {
10303            int N = providers.size();
10304            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10305            for (int i=0; i<N; i++) {
10306                // TODO: keep logic in sync with installEncryptionUnawareProviders
10307                ProviderInfo cpi =
10308                    (ProviderInfo)providers.get(i);
10309                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10310                        cpi.name, cpi.flags);
10311                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10312                    // This is a singleton provider, but a user besides the
10313                    // default user is asking to initialize a process it runs
10314                    // in...  well, no, it doesn't actually run in this process,
10315                    // it runs in the process of the default user.  Get rid of it.
10316                    providers.remove(i);
10317                    N--;
10318                    i--;
10319                    continue;
10320                }
10321
10322                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10323                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10324                if (cpr == null) {
10325                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10326                    mProviderMap.putProviderByClass(comp, cpr);
10327                }
10328                if (DEBUG_MU) Slog.v(TAG_MU,
10329                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10330                app.pubProviders.put(cpi.name, cpr);
10331                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10332                    // Don't add this if it is a platform component that is marked
10333                    // to run in multiple processes, because this is actually
10334                    // part of the framework so doesn't make sense to track as a
10335                    // separate apk in the process.
10336                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10337                            mProcessStats);
10338                }
10339                notifyPackageUse(cpi.applicationInfo.packageName,
10340                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10341            }
10342        }
10343        return providers;
10344    }
10345
10346    /**
10347     * Check if {@link ProcessRecord} has a possible chance at accessing the
10348     * given {@link ProviderInfo}. Final permission checking is always done
10349     * in {@link ContentProvider}.
10350     */
10351    private final String checkContentProviderPermissionLocked(
10352            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10353        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10354        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10355        boolean checkedGrants = false;
10356        if (checkUser) {
10357            // Looking for cross-user grants before enforcing the typical cross-users permissions
10358            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10359            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10360                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10361                    return null;
10362                }
10363                checkedGrants = true;
10364            }
10365            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10366                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10367            if (userId != tmpTargetUserId) {
10368                // When we actually went to determine the final targer user ID, this ended
10369                // up different than our initial check for the authority.  This is because
10370                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10371                // SELF.  So we need to re-check the grants again.
10372                checkedGrants = false;
10373            }
10374        }
10375        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10376                cpi.applicationInfo.uid, cpi.exported)
10377                == PackageManager.PERMISSION_GRANTED) {
10378            return null;
10379        }
10380        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10381                cpi.applicationInfo.uid, cpi.exported)
10382                == PackageManager.PERMISSION_GRANTED) {
10383            return null;
10384        }
10385
10386        PathPermission[] pps = cpi.pathPermissions;
10387        if (pps != null) {
10388            int i = pps.length;
10389            while (i > 0) {
10390                i--;
10391                PathPermission pp = pps[i];
10392                String pprperm = pp.getReadPermission();
10393                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10394                        cpi.applicationInfo.uid, cpi.exported)
10395                        == PackageManager.PERMISSION_GRANTED) {
10396                    return null;
10397                }
10398                String ppwperm = pp.getWritePermission();
10399                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10400                        cpi.applicationInfo.uid, cpi.exported)
10401                        == PackageManager.PERMISSION_GRANTED) {
10402                    return null;
10403                }
10404            }
10405        }
10406        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10407            return null;
10408        }
10409
10410        String msg;
10411        if (!cpi.exported) {
10412            msg = "Permission Denial: opening provider " + cpi.name
10413                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10414                    + ", uid=" + callingUid + ") that is not exported from uid "
10415                    + cpi.applicationInfo.uid;
10416        } else {
10417            msg = "Permission Denial: opening provider " + cpi.name
10418                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10419                    + ", uid=" + callingUid + ") requires "
10420                    + cpi.readPermission + " or " + cpi.writePermission;
10421        }
10422        Slog.w(TAG, msg);
10423        return msg;
10424    }
10425
10426    /**
10427     * Returns if the ContentProvider has granted a uri to callingUid
10428     */
10429    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10430        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10431        if (perms != null) {
10432            for (int i=perms.size()-1; i>=0; i--) {
10433                GrantUri grantUri = perms.keyAt(i);
10434                if (grantUri.sourceUserId == userId || !checkUser) {
10435                    if (matchesProvider(grantUri.uri, cpi)) {
10436                        return true;
10437                    }
10438                }
10439            }
10440        }
10441        return false;
10442    }
10443
10444    /**
10445     * Returns true if the uri authority is one of the authorities specified in the provider.
10446     */
10447    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10448        String uriAuth = uri.getAuthority();
10449        String cpiAuth = cpi.authority;
10450        if (cpiAuth.indexOf(';') == -1) {
10451            return cpiAuth.equals(uriAuth);
10452        }
10453        String[] cpiAuths = cpiAuth.split(";");
10454        int length = cpiAuths.length;
10455        for (int i = 0; i < length; i++) {
10456            if (cpiAuths[i].equals(uriAuth)) return true;
10457        }
10458        return false;
10459    }
10460
10461    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10462            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10463        if (r != null) {
10464            for (int i=0; i<r.conProviders.size(); i++) {
10465                ContentProviderConnection conn = r.conProviders.get(i);
10466                if (conn.provider == cpr) {
10467                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10468                            "Adding provider requested by "
10469                            + r.processName + " from process "
10470                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10471                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10472                    if (stable) {
10473                        conn.stableCount++;
10474                        conn.numStableIncs++;
10475                    } else {
10476                        conn.unstableCount++;
10477                        conn.numUnstableIncs++;
10478                    }
10479                    return conn;
10480                }
10481            }
10482            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10483            if (stable) {
10484                conn.stableCount = 1;
10485                conn.numStableIncs = 1;
10486            } else {
10487                conn.unstableCount = 1;
10488                conn.numUnstableIncs = 1;
10489            }
10490            cpr.connections.add(conn);
10491            r.conProviders.add(conn);
10492            startAssociationLocked(r.uid, r.processName, r.curProcState,
10493                    cpr.uid, cpr.name, cpr.info.processName);
10494            return conn;
10495        }
10496        cpr.addExternalProcessHandleLocked(externalProcessToken);
10497        return null;
10498    }
10499
10500    boolean decProviderCountLocked(ContentProviderConnection conn,
10501            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10502        if (conn != null) {
10503            cpr = conn.provider;
10504            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10505                    "Removing provider requested by "
10506                    + conn.client.processName + " from process "
10507                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10508                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10509            if (stable) {
10510                conn.stableCount--;
10511            } else {
10512                conn.unstableCount--;
10513            }
10514            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10515                cpr.connections.remove(conn);
10516                conn.client.conProviders.remove(conn);
10517                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10518                    // The client is more important than last activity -- note the time this
10519                    // is happening, so we keep the old provider process around a bit as last
10520                    // activity to avoid thrashing it.
10521                    if (cpr.proc != null) {
10522                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10523                    }
10524                }
10525                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10526                return true;
10527            }
10528            return false;
10529        }
10530        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10531        return false;
10532    }
10533
10534    private void checkTime(long startTime, String where) {
10535        long now = SystemClock.uptimeMillis();
10536        if ((now-startTime) > 50) {
10537            // If we are taking more than 50ms, log about it.
10538            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10539        }
10540    }
10541
10542    private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
10543            PROC_SPACE_TERM,
10544            PROC_SPACE_TERM|PROC_PARENS,
10545            PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
10546    };
10547
10548    private final long[] mProcessStateStatsLongs = new long[1];
10549
10550    boolean isProcessAliveLocked(ProcessRecord proc) {
10551        if (proc.procStatFile == null) {
10552            proc.procStatFile = "/proc/" + proc.pid + "/stat";
10553        }
10554        mProcessStateStatsLongs[0] = 0;
10555        if (!Process.readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
10556                mProcessStateStatsLongs, null)) {
10557            if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
10558            return false;
10559        }
10560        final long state = mProcessStateStatsLongs[0];
10561        if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
10562                + (char)state);
10563        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
10564    }
10565
10566    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10567            String name, IBinder token, boolean stable, int userId) {
10568        ContentProviderRecord cpr;
10569        ContentProviderConnection conn = null;
10570        ProviderInfo cpi = null;
10571
10572        synchronized(this) {
10573            long startTime = SystemClock.uptimeMillis();
10574
10575            ProcessRecord r = null;
10576            if (caller != null) {
10577                r = getRecordForAppLocked(caller);
10578                if (r == null) {
10579                    throw new SecurityException(
10580                            "Unable to find app for caller " + caller
10581                          + " (pid=" + Binder.getCallingPid()
10582                          + ") when getting content provider " + name);
10583                }
10584            }
10585
10586            boolean checkCrossUser = true;
10587
10588            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10589
10590            // First check if this content provider has been published...
10591            cpr = mProviderMap.getProviderByName(name, userId);
10592            // If that didn't work, check if it exists for user 0 and then
10593            // verify that it's a singleton provider before using it.
10594            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10595                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10596                if (cpr != null) {
10597                    cpi = cpr.info;
10598                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10599                            cpi.name, cpi.flags)
10600                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10601                        userId = UserHandle.USER_SYSTEM;
10602                        checkCrossUser = false;
10603                    } else {
10604                        cpr = null;
10605                        cpi = null;
10606                    }
10607                }
10608            }
10609
10610            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
10611            if (providerRunning) {
10612                cpi = cpr.info;
10613                String msg;
10614                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10615                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10616                        != null) {
10617                    throw new SecurityException(msg);
10618                }
10619                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10620
10621                if (r != null && cpr.canRunHere(r)) {
10622                    // This provider has been published or is in the process
10623                    // of being published...  but it is also allowed to run
10624                    // in the caller's process, so don't make a connection
10625                    // and just let the caller instantiate its own instance.
10626                    ContentProviderHolder holder = cpr.newHolder(null);
10627                    // don't give caller the provider object, it needs
10628                    // to make its own.
10629                    holder.provider = null;
10630                    return holder;
10631                }
10632
10633                final long origId = Binder.clearCallingIdentity();
10634
10635                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10636
10637                // In this case the provider instance already exists, so we can
10638                // return it right away.
10639                conn = incProviderCountLocked(r, cpr, token, stable);
10640                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10641                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10642                        // If this is a perceptible app accessing the provider,
10643                        // make sure to count it as being accessed and thus
10644                        // back up on the LRU list.  This is good because
10645                        // content providers are often expensive to start.
10646                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10647                        updateLruProcessLocked(cpr.proc, false, null);
10648                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10649                    }
10650                }
10651
10652                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10653                final int verifiedAdj = cpr.proc.verifiedAdj;
10654                boolean success = updateOomAdjLocked(cpr.proc);
10655                // XXX things have changed so updateOomAdjLocked doesn't actually tell us
10656                // if the process has been successfully adjusted.  So to reduce races with
10657                // it, we will check whether the process still exists.  Note that this doesn't
10658                // completely get rid of races with LMK killing the process, but should make
10659                // them much smaller.
10660                if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
10661                    success = false;
10662                }
10663                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10664                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10665                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10666                // NOTE: there is still a race here where a signal could be
10667                // pending on the process even though we managed to update its
10668                // adj level.  Not sure what to do about this, but at least
10669                // the race is now smaller.
10670                if (!success) {
10671                    // Uh oh...  it looks like the provider's process
10672                    // has been killed on us.  We need to wait for a new
10673                    // process to be started, and make sure its death
10674                    // doesn't kill our process.
10675                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10676                            + " is crashing; detaching " + r);
10677                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10678                    checkTime(startTime, "getContentProviderImpl: before appDied");
10679                    appDiedLocked(cpr.proc);
10680                    checkTime(startTime, "getContentProviderImpl: after appDied");
10681                    if (!lastRef) {
10682                        // This wasn't the last ref our process had on
10683                        // the provider...  we have now been killed, bail.
10684                        return null;
10685                    }
10686                    providerRunning = false;
10687                    conn = null;
10688                } else {
10689                    cpr.proc.verifiedAdj = cpr.proc.setAdj;
10690                }
10691
10692                Binder.restoreCallingIdentity(origId);
10693            }
10694
10695            if (!providerRunning) {
10696                try {
10697                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10698                    cpi = AppGlobals.getPackageManager().
10699                        resolveContentProvider(name,
10700                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10701                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10702                } catch (RemoteException ex) {
10703                }
10704                if (cpi == null) {
10705                    return null;
10706                }
10707                // If the provider is a singleton AND
10708                // (it's a call within the same user || the provider is a
10709                // privileged app)
10710                // Then allow connecting to the singleton provider
10711                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10712                        cpi.name, cpi.flags)
10713                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10714                if (singleton) {
10715                    userId = UserHandle.USER_SYSTEM;
10716                }
10717                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10718                checkTime(startTime, "getContentProviderImpl: got app info for user");
10719
10720                String msg;
10721                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10722                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10723                        != null) {
10724                    throw new SecurityException(msg);
10725                }
10726                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10727
10728                if (!mProcessesReady
10729                        && !cpi.processName.equals("system")) {
10730                    // If this content provider does not run in the system
10731                    // process, and the system is not yet ready to run other
10732                    // processes, then fail fast instead of hanging.
10733                    throw new IllegalArgumentException(
10734                            "Attempt to launch content provider before system ready");
10735                }
10736
10737                // Make sure that the user who owns this provider is running.  If not,
10738                // we don't want to allow it to run.
10739                if (!mUserController.isUserRunningLocked(userId, 0)) {
10740                    Slog.w(TAG, "Unable to launch app "
10741                            + cpi.applicationInfo.packageName + "/"
10742                            + cpi.applicationInfo.uid + " for provider "
10743                            + name + ": user " + userId + " is stopped");
10744                    return null;
10745                }
10746
10747                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10748                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10749                cpr = mProviderMap.getProviderByClass(comp, userId);
10750                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10751                final boolean firstClass = cpr == null;
10752                if (firstClass) {
10753                    final long ident = Binder.clearCallingIdentity();
10754
10755                    // If permissions need a review before any of the app components can run,
10756                    // we return no provider and launch a review activity if the calling app
10757                    // is in the foreground.
10758                    if (mPermissionReviewRequired) {
10759                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10760                            return null;
10761                        }
10762                    }
10763
10764                    try {
10765                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10766                        ApplicationInfo ai =
10767                            AppGlobals.getPackageManager().
10768                                getApplicationInfo(
10769                                        cpi.applicationInfo.packageName,
10770                                        STOCK_PM_FLAGS, userId);
10771                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10772                        if (ai == null) {
10773                            Slog.w(TAG, "No package info for content provider "
10774                                    + cpi.name);
10775                            return null;
10776                        }
10777                        ai = getAppInfoForUser(ai, userId);
10778                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10779                    } catch (RemoteException ex) {
10780                        // pm is in same process, this will never happen.
10781                    } finally {
10782                        Binder.restoreCallingIdentity(ident);
10783                    }
10784                }
10785
10786                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10787
10788                if (r != null && cpr.canRunHere(r)) {
10789                    // If this is a multiprocess provider, then just return its
10790                    // info and allow the caller to instantiate it.  Only do
10791                    // this if the provider is the same user as the caller's
10792                    // process, or can run as root (so can be in any process).
10793                    return cpr.newHolder(null);
10794                }
10795
10796                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10797                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10798                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10799
10800                // This is single process, and our app is now connecting to it.
10801                // See if we are already in the process of launching this
10802                // provider.
10803                final int N = mLaunchingProviders.size();
10804                int i;
10805                for (i = 0; i < N; i++) {
10806                    if (mLaunchingProviders.get(i) == cpr) {
10807                        break;
10808                    }
10809                }
10810
10811                // If the provider is not already being launched, then get it
10812                // started.
10813                if (i >= N) {
10814                    final long origId = Binder.clearCallingIdentity();
10815
10816                    try {
10817                        // Content provider is now in use, its package can't be stopped.
10818                        try {
10819                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10820                            AppGlobals.getPackageManager().setPackageStoppedState(
10821                                    cpr.appInfo.packageName, false, userId);
10822                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10823                        } catch (RemoteException e) {
10824                        } catch (IllegalArgumentException e) {
10825                            Slog.w(TAG, "Failed trying to unstop package "
10826                                    + cpr.appInfo.packageName + ": " + e);
10827                        }
10828
10829                        // Use existing process if already started
10830                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10831                        ProcessRecord proc = getProcessRecordLocked(
10832                                cpi.processName, cpr.appInfo.uid, false);
10833                        if (proc != null && proc.thread != null && !proc.killed) {
10834                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10835                                    "Installing in existing process " + proc);
10836                            if (!proc.pubProviders.containsKey(cpi.name)) {
10837                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10838                                proc.pubProviders.put(cpi.name, cpr);
10839                                try {
10840                                    proc.thread.scheduleInstallProvider(cpi);
10841                                } catch (RemoteException e) {
10842                                }
10843                            }
10844                        } else {
10845                            checkTime(startTime, "getContentProviderImpl: before start process");
10846                            proc = startProcessLocked(cpi.processName,
10847                                    cpr.appInfo, false, 0, "content provider",
10848                                    new ComponentName(cpi.applicationInfo.packageName,
10849                                            cpi.name), false, false, false);
10850                            checkTime(startTime, "getContentProviderImpl: after start process");
10851                            if (proc == null) {
10852                                Slog.w(TAG, "Unable to launch app "
10853                                        + cpi.applicationInfo.packageName + "/"
10854                                        + cpi.applicationInfo.uid + " for provider "
10855                                        + name + ": process is bad");
10856                                return null;
10857                            }
10858                        }
10859                        cpr.launchingApp = proc;
10860                        mLaunchingProviders.add(cpr);
10861                    } finally {
10862                        Binder.restoreCallingIdentity(origId);
10863                    }
10864                }
10865
10866                checkTime(startTime, "getContentProviderImpl: updating data structures");
10867
10868                // Make sure the provider is published (the same provider class
10869                // may be published under multiple names).
10870                if (firstClass) {
10871                    mProviderMap.putProviderByClass(comp, cpr);
10872                }
10873
10874                mProviderMap.putProviderByName(name, cpr);
10875                conn = incProviderCountLocked(r, cpr, token, stable);
10876                if (conn != null) {
10877                    conn.waiting = true;
10878                }
10879            }
10880            checkTime(startTime, "getContentProviderImpl: done!");
10881        }
10882
10883        // Wait for the provider to be published...
10884        synchronized (cpr) {
10885            while (cpr.provider == null) {
10886                if (cpr.launchingApp == null) {
10887                    Slog.w(TAG, "Unable to launch app "
10888                            + cpi.applicationInfo.packageName + "/"
10889                            + cpi.applicationInfo.uid + " for provider "
10890                            + name + ": launching app became null");
10891                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10892                            UserHandle.getUserId(cpi.applicationInfo.uid),
10893                            cpi.applicationInfo.packageName,
10894                            cpi.applicationInfo.uid, name);
10895                    return null;
10896                }
10897                try {
10898                    if (DEBUG_MU) Slog.v(TAG_MU,
10899                            "Waiting to start provider " + cpr
10900                            + " launchingApp=" + cpr.launchingApp);
10901                    if (conn != null) {
10902                        conn.waiting = true;
10903                    }
10904                    cpr.wait();
10905                } catch (InterruptedException ex) {
10906                } finally {
10907                    if (conn != null) {
10908                        conn.waiting = false;
10909                    }
10910                }
10911            }
10912        }
10913        return cpr != null ? cpr.newHolder(conn) : null;
10914    }
10915
10916    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10917            ProcessRecord r, final int userId) {
10918        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10919                cpi.packageName, userId)) {
10920
10921            final boolean callerForeground = r == null || r.setSchedGroup
10922                    != ProcessList.SCHED_GROUP_BACKGROUND;
10923
10924            // Show a permission review UI only for starting from a foreground app
10925            if (!callerForeground) {
10926                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10927                        + cpi.packageName + " requires a permissions review");
10928                return false;
10929            }
10930
10931            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10932            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10933                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10934            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10935
10936            if (DEBUG_PERMISSIONS_REVIEW) {
10937                Slog.i(TAG, "u" + userId + " Launching permission review "
10938                        + "for package " + cpi.packageName);
10939            }
10940
10941            final UserHandle userHandle = new UserHandle(userId);
10942            mHandler.post(new Runnable() {
10943                @Override
10944                public void run() {
10945                    mContext.startActivityAsUser(intent, userHandle);
10946                }
10947            });
10948
10949            return false;
10950        }
10951
10952        return true;
10953    }
10954
10955    PackageManagerInternal getPackageManagerInternalLocked() {
10956        if (mPackageManagerInt == null) {
10957            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10958        }
10959        return mPackageManagerInt;
10960    }
10961
10962    @Override
10963    public final ContentProviderHolder getContentProvider(
10964            IApplicationThread caller, String name, int userId, boolean stable) {
10965        enforceNotIsolatedCaller("getContentProvider");
10966        if (caller == null) {
10967            String msg = "null IApplicationThread when getting content provider "
10968                    + name;
10969            Slog.w(TAG, msg);
10970            throw new SecurityException(msg);
10971        }
10972        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10973        // with cross-user grant.
10974        return getContentProviderImpl(caller, name, null, stable, userId);
10975    }
10976
10977    public ContentProviderHolder getContentProviderExternal(
10978            String name, int userId, IBinder token) {
10979        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10980            "Do not have permission in call getContentProviderExternal()");
10981        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10982                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10983        return getContentProviderExternalUnchecked(name, token, userId);
10984    }
10985
10986    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10987            IBinder token, int userId) {
10988        return getContentProviderImpl(null, name, token, true, userId);
10989    }
10990
10991    /**
10992     * Drop a content provider from a ProcessRecord's bookkeeping
10993     */
10994    public void removeContentProvider(IBinder connection, boolean stable) {
10995        enforceNotIsolatedCaller("removeContentProvider");
10996        long ident = Binder.clearCallingIdentity();
10997        try {
10998            synchronized (this) {
10999                ContentProviderConnection conn;
11000                try {
11001                    conn = (ContentProviderConnection)connection;
11002                } catch (ClassCastException e) {
11003                    String msg ="removeContentProvider: " + connection
11004                            + " not a ContentProviderConnection";
11005                    Slog.w(TAG, msg);
11006                    throw new IllegalArgumentException(msg);
11007                }
11008                if (conn == null) {
11009                    throw new NullPointerException("connection is null");
11010                }
11011                if (decProviderCountLocked(conn, null, null, stable)) {
11012                    updateOomAdjLocked();
11013                }
11014            }
11015        } finally {
11016            Binder.restoreCallingIdentity(ident);
11017        }
11018    }
11019
11020    public void removeContentProviderExternal(String name, IBinder token) {
11021        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11022            "Do not have permission in call removeContentProviderExternal()");
11023        int userId = UserHandle.getCallingUserId();
11024        long ident = Binder.clearCallingIdentity();
11025        try {
11026            removeContentProviderExternalUnchecked(name, token, userId);
11027        } finally {
11028            Binder.restoreCallingIdentity(ident);
11029        }
11030    }
11031
11032    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11033        synchronized (this) {
11034            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11035            if(cpr == null) {
11036                //remove from mProvidersByClass
11037                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11038                return;
11039            }
11040
11041            //update content provider record entry info
11042            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11043            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11044            if (localCpr.hasExternalProcessHandles()) {
11045                if (localCpr.removeExternalProcessHandleLocked(token)) {
11046                    updateOomAdjLocked();
11047                } else {
11048                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11049                            + " with no external reference for token: "
11050                            + token + ".");
11051                }
11052            } else {
11053                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11054                        + " with no external references.");
11055            }
11056        }
11057    }
11058
11059    public final void publishContentProviders(IApplicationThread caller,
11060            List<ContentProviderHolder> providers) {
11061        if (providers == null) {
11062            return;
11063        }
11064
11065        enforceNotIsolatedCaller("publishContentProviders");
11066        synchronized (this) {
11067            final ProcessRecord r = getRecordForAppLocked(caller);
11068            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11069            if (r == null) {
11070                throw new SecurityException(
11071                        "Unable to find app for caller " + caller
11072                      + " (pid=" + Binder.getCallingPid()
11073                      + ") when publishing content providers");
11074            }
11075
11076            final long origId = Binder.clearCallingIdentity();
11077
11078            final int N = providers.size();
11079            for (int i = 0; i < N; i++) {
11080                ContentProviderHolder src = providers.get(i);
11081                if (src == null || src.info == null || src.provider == null) {
11082                    continue;
11083                }
11084                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11085                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11086                if (dst != null) {
11087                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11088                    mProviderMap.putProviderByClass(comp, dst);
11089                    String names[] = dst.info.authority.split(";");
11090                    for (int j = 0; j < names.length; j++) {
11091                        mProviderMap.putProviderByName(names[j], dst);
11092                    }
11093
11094                    int launchingCount = mLaunchingProviders.size();
11095                    int j;
11096                    boolean wasInLaunchingProviders = false;
11097                    for (j = 0; j < launchingCount; j++) {
11098                        if (mLaunchingProviders.get(j) == dst) {
11099                            mLaunchingProviders.remove(j);
11100                            wasInLaunchingProviders = true;
11101                            j--;
11102                            launchingCount--;
11103                        }
11104                    }
11105                    if (wasInLaunchingProviders) {
11106                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11107                    }
11108                    synchronized (dst) {
11109                        dst.provider = src.provider;
11110                        dst.proc = r;
11111                        dst.notifyAll();
11112                    }
11113                    updateOomAdjLocked(r);
11114                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11115                            src.info.authority);
11116                }
11117            }
11118
11119            Binder.restoreCallingIdentity(origId);
11120        }
11121    }
11122
11123    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11124        ContentProviderConnection conn;
11125        try {
11126            conn = (ContentProviderConnection)connection;
11127        } catch (ClassCastException e) {
11128            String msg ="refContentProvider: " + connection
11129                    + " not a ContentProviderConnection";
11130            Slog.w(TAG, msg);
11131            throw new IllegalArgumentException(msg);
11132        }
11133        if (conn == null) {
11134            throw new NullPointerException("connection is null");
11135        }
11136
11137        synchronized (this) {
11138            if (stable > 0) {
11139                conn.numStableIncs += stable;
11140            }
11141            stable = conn.stableCount + stable;
11142            if (stable < 0) {
11143                throw new IllegalStateException("stableCount < 0: " + stable);
11144            }
11145
11146            if (unstable > 0) {
11147                conn.numUnstableIncs += unstable;
11148            }
11149            unstable = conn.unstableCount + unstable;
11150            if (unstable < 0) {
11151                throw new IllegalStateException("unstableCount < 0: " + unstable);
11152            }
11153
11154            if ((stable+unstable) <= 0) {
11155                throw new IllegalStateException("ref counts can't go to zero here: stable="
11156                        + stable + " unstable=" + unstable);
11157            }
11158            conn.stableCount = stable;
11159            conn.unstableCount = unstable;
11160            return !conn.dead;
11161        }
11162    }
11163
11164    public void unstableProviderDied(IBinder connection) {
11165        ContentProviderConnection conn;
11166        try {
11167            conn = (ContentProviderConnection)connection;
11168        } catch (ClassCastException e) {
11169            String msg ="refContentProvider: " + connection
11170                    + " not a ContentProviderConnection";
11171            Slog.w(TAG, msg);
11172            throw new IllegalArgumentException(msg);
11173        }
11174        if (conn == null) {
11175            throw new NullPointerException("connection is null");
11176        }
11177
11178        // Safely retrieve the content provider associated with the connection.
11179        IContentProvider provider;
11180        synchronized (this) {
11181            provider = conn.provider.provider;
11182        }
11183
11184        if (provider == null) {
11185            // Um, yeah, we're way ahead of you.
11186            return;
11187        }
11188
11189        // Make sure the caller is being honest with us.
11190        if (provider.asBinder().pingBinder()) {
11191            // Er, no, still looks good to us.
11192            synchronized (this) {
11193                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11194                        + " says " + conn + " died, but we don't agree");
11195                return;
11196            }
11197        }
11198
11199        // Well look at that!  It's dead!
11200        synchronized (this) {
11201            if (conn.provider.provider != provider) {
11202                // But something changed...  good enough.
11203                return;
11204            }
11205
11206            ProcessRecord proc = conn.provider.proc;
11207            if (proc == null || proc.thread == null) {
11208                // Seems like the process is already cleaned up.
11209                return;
11210            }
11211
11212            // As far as we're concerned, this is just like receiving a
11213            // death notification...  just a bit prematurely.
11214            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11215                    + ") early provider death");
11216            final long ident = Binder.clearCallingIdentity();
11217            try {
11218                appDiedLocked(proc);
11219            } finally {
11220                Binder.restoreCallingIdentity(ident);
11221            }
11222        }
11223    }
11224
11225    @Override
11226    public void appNotRespondingViaProvider(IBinder connection) {
11227        enforceCallingPermission(
11228                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11229
11230        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11231        if (conn == null) {
11232            Slog.w(TAG, "ContentProviderConnection is null");
11233            return;
11234        }
11235
11236        final ProcessRecord host = conn.provider.proc;
11237        if (host == null) {
11238            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11239            return;
11240        }
11241
11242        mHandler.post(new Runnable() {
11243            @Override
11244            public void run() {
11245                mAppErrors.appNotResponding(host, null, null, false,
11246                        "ContentProvider not responding");
11247            }
11248        });
11249    }
11250
11251    public final void installSystemProviders() {
11252        List<ProviderInfo> providers;
11253        synchronized (this) {
11254            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11255            providers = generateApplicationProvidersLocked(app);
11256            if (providers != null) {
11257                for (int i=providers.size()-1; i>=0; i--) {
11258                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11259                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11260                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11261                                + ": not system .apk");
11262                        providers.remove(i);
11263                    }
11264                }
11265            }
11266        }
11267        if (providers != null) {
11268            mSystemThread.installSystemProviders(providers);
11269        }
11270
11271        mCoreSettingsObserver = new CoreSettingsObserver(this);
11272        mFontScaleSettingObserver = new FontScaleSettingObserver();
11273
11274        //mUsageStatsService.monitorPackages();
11275    }
11276
11277    private void startPersistentApps(int matchFlags) {
11278        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11279
11280        synchronized (this) {
11281            try {
11282                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11283                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11284                for (ApplicationInfo app : apps) {
11285                    if (!"android".equals(app.packageName)) {
11286                        addAppLocked(app, false, null /* ABI override */);
11287                    }
11288                }
11289            } catch (RemoteException ex) {
11290            }
11291        }
11292    }
11293
11294    /**
11295     * When a user is unlocked, we need to install encryption-unaware providers
11296     * belonging to any running apps.
11297     */
11298    private void installEncryptionUnawareProviders(int userId) {
11299        // We're only interested in providers that are encryption unaware, and
11300        // we don't care about uninstalled apps, since there's no way they're
11301        // running at this point.
11302        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11303
11304        synchronized (this) {
11305            final int NP = mProcessNames.getMap().size();
11306            for (int ip = 0; ip < NP; ip++) {
11307                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11308                final int NA = apps.size();
11309                for (int ia = 0; ia < NA; ia++) {
11310                    final ProcessRecord app = apps.valueAt(ia);
11311                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11312
11313                    final int NG = app.pkgList.size();
11314                    for (int ig = 0; ig < NG; ig++) {
11315                        try {
11316                            final String pkgName = app.pkgList.keyAt(ig);
11317                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11318                                    .getPackageInfo(pkgName, matchFlags, userId);
11319                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11320                                for (ProviderInfo pi : pkgInfo.providers) {
11321                                    // TODO: keep in sync with generateApplicationProvidersLocked
11322                                    final boolean processMatch = Objects.equals(pi.processName,
11323                                            app.processName) || pi.multiprocess;
11324                                    final boolean userMatch = isSingleton(pi.processName,
11325                                            pi.applicationInfo, pi.name, pi.flags)
11326                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
11327                                    if (processMatch && userMatch) {
11328                                        Log.v(TAG, "Installing " + pi);
11329                                        app.thread.scheduleInstallProvider(pi);
11330                                    } else {
11331                                        Log.v(TAG, "Skipping " + pi);
11332                                    }
11333                                }
11334                            }
11335                        } catch (RemoteException ignored) {
11336                        }
11337                    }
11338                }
11339            }
11340        }
11341    }
11342
11343    /**
11344     * Allows apps to retrieve the MIME type of a URI.
11345     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11346     * users, then it does not need permission to access the ContentProvider.
11347     * Either, it needs cross-user uri grants.
11348     *
11349     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11350     *
11351     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11352     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11353     */
11354    public String getProviderMimeType(Uri uri, int userId) {
11355        enforceNotIsolatedCaller("getProviderMimeType");
11356        final String name = uri.getAuthority();
11357        int callingUid = Binder.getCallingUid();
11358        int callingPid = Binder.getCallingPid();
11359        long ident = 0;
11360        boolean clearedIdentity = false;
11361        synchronized (this) {
11362            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11363        }
11364        if (canClearIdentity(callingPid, callingUid, userId)) {
11365            clearedIdentity = true;
11366            ident = Binder.clearCallingIdentity();
11367        }
11368        ContentProviderHolder holder = null;
11369        try {
11370            holder = getContentProviderExternalUnchecked(name, null, userId);
11371            if (holder != null) {
11372                return holder.provider.getType(uri);
11373            }
11374        } catch (RemoteException e) {
11375            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11376            return null;
11377        } catch (Exception e) {
11378            Log.w(TAG, "Exception while determining type of " + uri, e);
11379            return null;
11380        } finally {
11381            // We need to clear the identity to call removeContentProviderExternalUnchecked
11382            if (!clearedIdentity) {
11383                ident = Binder.clearCallingIdentity();
11384            }
11385            try {
11386                if (holder != null) {
11387                    removeContentProviderExternalUnchecked(name, null, userId);
11388                }
11389            } finally {
11390                Binder.restoreCallingIdentity(ident);
11391            }
11392        }
11393
11394        return null;
11395    }
11396
11397    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11398        if (UserHandle.getUserId(callingUid) == userId) {
11399            return true;
11400        }
11401        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11402                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11403                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11404                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11405                return true;
11406        }
11407        return false;
11408    }
11409
11410    // =========================================================
11411    // GLOBAL MANAGEMENT
11412    // =========================================================
11413
11414    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11415            boolean isolated, int isolatedUid) {
11416        String proc = customProcess != null ? customProcess : info.processName;
11417        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11418        final int userId = UserHandle.getUserId(info.uid);
11419        int uid = info.uid;
11420        if (isolated) {
11421            if (isolatedUid == 0) {
11422                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11423                while (true) {
11424                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11425                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11426                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11427                    }
11428                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11429                    mNextIsolatedProcessUid++;
11430                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11431                        // No process for this uid, use it.
11432                        break;
11433                    }
11434                    stepsLeft--;
11435                    if (stepsLeft <= 0) {
11436                        return null;
11437                    }
11438                }
11439            } else {
11440                // Special case for startIsolatedProcess (internal only), where
11441                // the uid of the isolated process is specified by the caller.
11442                uid = isolatedUid;
11443            }
11444
11445            // Register the isolated UID with this application so BatteryStats knows to
11446            // attribute resource usage to the application.
11447            //
11448            // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
11449            // about the process state of the isolated UID *before* it is registered with the
11450            // owning application.
11451            mBatteryStatsService.addIsolatedUid(uid, info.uid);
11452        }
11453        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11454        if (!mBooted && !mBooting
11455                && userId == UserHandle.USER_SYSTEM
11456                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11457            r.persistent = true;
11458            r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11459        }
11460        addProcessNameLocked(r);
11461        return r;
11462    }
11463
11464    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11465            String abiOverride) {
11466        ProcessRecord app;
11467        if (!isolated) {
11468            app = getProcessRecordLocked(info.processName, info.uid, true);
11469        } else {
11470            app = null;
11471        }
11472
11473        if (app == null) {
11474            app = newProcessRecordLocked(info, null, isolated, 0);
11475            updateLruProcessLocked(app, false, null);
11476            updateOomAdjLocked();
11477        }
11478
11479        // This package really, really can not be stopped.
11480        try {
11481            AppGlobals.getPackageManager().setPackageStoppedState(
11482                    info.packageName, false, UserHandle.getUserId(app.uid));
11483        } catch (RemoteException e) {
11484        } catch (IllegalArgumentException e) {
11485            Slog.w(TAG, "Failed trying to unstop package "
11486                    + info.packageName + ": " + e);
11487        }
11488
11489        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11490            app.persistent = true;
11491            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11492        }
11493        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11494            mPersistentStartingProcesses.add(app);
11495            startProcessLocked(app, "added application", app.processName, abiOverride,
11496                    null /* entryPoint */, null /* entryPointArgs */);
11497        }
11498
11499        return app;
11500    }
11501
11502    public void unhandledBack() {
11503        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11504                "unhandledBack()");
11505
11506        synchronized(this) {
11507            final long origId = Binder.clearCallingIdentity();
11508            try {
11509                getFocusedStack().unhandledBackLocked();
11510            } finally {
11511                Binder.restoreCallingIdentity(origId);
11512            }
11513        }
11514    }
11515
11516    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11517        enforceNotIsolatedCaller("openContentUri");
11518        final int userId = UserHandle.getCallingUserId();
11519        String name = uri.getAuthority();
11520        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11521        ParcelFileDescriptor pfd = null;
11522        if (cph != null) {
11523            // We record the binder invoker's uid in thread-local storage before
11524            // going to the content provider to open the file.  Later, in the code
11525            // that handles all permissions checks, we look for this uid and use
11526            // that rather than the Activity Manager's own uid.  The effect is that
11527            // we do the check against the caller's permissions even though it looks
11528            // to the content provider like the Activity Manager itself is making
11529            // the request.
11530            Binder token = new Binder();
11531            sCallerIdentity.set(new Identity(
11532                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11533            try {
11534                pfd = cph.provider.openFile(null, uri, "r", null, token);
11535            } catch (FileNotFoundException e) {
11536                // do nothing; pfd will be returned null
11537            } finally {
11538                // Ensure that whatever happens, we clean up the identity state
11539                sCallerIdentity.remove();
11540                // Ensure we're done with the provider.
11541                removeContentProviderExternalUnchecked(name, null, userId);
11542            }
11543        } else {
11544            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11545        }
11546        return pfd;
11547    }
11548
11549    // Actually is sleeping or shutting down or whatever else in the future
11550    // is an inactive state.
11551    boolean isSleepingOrShuttingDownLocked() {
11552        return isSleepingLocked() || mShuttingDown;
11553    }
11554
11555    boolean isShuttingDownLocked() {
11556        return mShuttingDown;
11557    }
11558
11559    boolean isSleepingLocked() {
11560        return mSleeping;
11561    }
11562
11563    void onWakefulnessChanged(int wakefulness) {
11564        synchronized(this) {
11565            mWakefulness = wakefulness;
11566            updateSleepIfNeededLocked();
11567        }
11568    }
11569
11570    void finishRunningVoiceLocked() {
11571        if (mRunningVoice != null) {
11572            mRunningVoice = null;
11573            mVoiceWakeLock.release();
11574            updateSleepIfNeededLocked();
11575        }
11576    }
11577
11578    void startTimeTrackingFocusedActivityLocked() {
11579        final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
11580        if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
11581            mCurAppTimeTracker.start(resumedActivity.packageName);
11582        }
11583    }
11584
11585    void updateSleepIfNeededLocked() {
11586        if (mSleeping && !shouldSleepLocked()) {
11587            mSleeping = false;
11588            startTimeTrackingFocusedActivityLocked();
11589            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11590            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11591            updateOomAdjLocked();
11592        } else if (!mSleeping && shouldSleepLocked()) {
11593            mSleeping = true;
11594            if (mCurAppTimeTracker != null) {
11595                mCurAppTimeTracker.stop();
11596            }
11597            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11598            mStackSupervisor.goingToSleepLocked();
11599            updateOomAdjLocked();
11600
11601            // Initialize the wake times of all processes.
11602            checkExcessivePowerUsageLocked(false);
11603            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11604            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11605            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11606        }
11607    }
11608
11609    private boolean shouldSleepLocked() {
11610        // Resume applications while running a voice interactor.
11611        if (mRunningVoice != null) {
11612            return false;
11613        }
11614
11615        // TODO: Transform the lock screen state into a sleep token instead.
11616        switch (mWakefulness) {
11617            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11618            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11619            case PowerManagerInternal.WAKEFULNESS_DOZING:
11620                // Pause applications whenever the lock screen is shown or any sleep
11621                // tokens have been acquired.
11622                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11623            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11624            default:
11625                // If we're asleep then pause applications unconditionally.
11626                return true;
11627        }
11628    }
11629
11630    /** Pokes the task persister. */
11631    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11632        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11633    }
11634
11635    /** Notifies all listeners when the pinned stack animation ends. */
11636    @Override
11637    public void notifyPinnedStackAnimationEnded() {
11638        mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
11639    }
11640
11641    @Override
11642    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11643        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11644    }
11645
11646    @Override
11647    public boolean shutdown(int timeout) {
11648        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11649                != PackageManager.PERMISSION_GRANTED) {
11650            throw new SecurityException("Requires permission "
11651                    + android.Manifest.permission.SHUTDOWN);
11652        }
11653
11654        boolean timedout = false;
11655
11656        synchronized(this) {
11657            mShuttingDown = true;
11658            updateEventDispatchingLocked();
11659            timedout = mStackSupervisor.shutdownLocked(timeout);
11660        }
11661
11662        mAppOpsService.shutdown();
11663        if (mUsageStatsService != null) {
11664            mUsageStatsService.prepareShutdown();
11665        }
11666        mBatteryStatsService.shutdown();
11667        synchronized (this) {
11668            mProcessStats.shutdownLocked();
11669            notifyTaskPersisterLocked(null, true);
11670        }
11671
11672        return timedout;
11673    }
11674
11675    public final void activitySlept(IBinder token) {
11676        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11677
11678        final long origId = Binder.clearCallingIdentity();
11679
11680        synchronized (this) {
11681            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11682            if (r != null) {
11683                mStackSupervisor.activitySleptLocked(r);
11684            }
11685        }
11686
11687        Binder.restoreCallingIdentity(origId);
11688    }
11689
11690    private String lockScreenShownToString() {
11691        switch (mLockScreenShown) {
11692            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11693            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11694            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11695            default: return "Unknown=" + mLockScreenShown;
11696        }
11697    }
11698
11699    void logLockScreen(String msg) {
11700        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11701                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11702                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11703                + " mSleeping=" + mSleeping);
11704    }
11705
11706    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11707        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11708        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11709        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11710            boolean wasRunningVoice = mRunningVoice != null;
11711            mRunningVoice = session;
11712            if (!wasRunningVoice) {
11713                mVoiceWakeLock.acquire();
11714                updateSleepIfNeededLocked();
11715            }
11716        }
11717    }
11718
11719    private void updateEventDispatchingLocked() {
11720        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11721    }
11722
11723    public void setLockScreenShown(boolean showing, boolean occluded) {
11724        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11725                != PackageManager.PERMISSION_GRANTED) {
11726            throw new SecurityException("Requires permission "
11727                    + android.Manifest.permission.DEVICE_POWER);
11728        }
11729
11730        synchronized(this) {
11731            long ident = Binder.clearCallingIdentity();
11732            try {
11733                if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11734                mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11735                if (showing && occluded) {
11736                    // The lock screen is currently showing, but is occluded by a window that can
11737                    // show on top of the lock screen. In this can we want to dismiss the docked
11738                    // stack since it will be complicated/risky to try to put the activity on top
11739                    // of the lock screen in the right fullscreen configuration.
11740                    mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11741                            mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11742                }
11743
11744                updateSleepIfNeededLocked();
11745            } finally {
11746                Binder.restoreCallingIdentity(ident);
11747            }
11748        }
11749    }
11750
11751    @Override
11752    public void notifyLockedProfile(@UserIdInt int userId) {
11753        try {
11754            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11755                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11756            }
11757        } catch (RemoteException ex) {
11758            throw new SecurityException("Fail to check is caller a privileged app", ex);
11759        }
11760
11761        synchronized (this) {
11762            if (mStackSupervisor.isUserLockedProfile(userId)) {
11763                final long ident = Binder.clearCallingIdentity();
11764                try {
11765                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11766                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11767                        // If there is no device lock, we will show the profile's credential page.
11768                        mActivityStarter.showConfirmDeviceCredential(userId);
11769                    } else {
11770                        // Showing launcher to avoid user entering credential twice.
11771                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11772                    }
11773                } finally {
11774                    Binder.restoreCallingIdentity(ident);
11775                }
11776            }
11777        }
11778    }
11779
11780    @Override
11781    public void startConfirmDeviceCredentialIntent(Intent intent) {
11782        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11783        synchronized (this) {
11784            final long ident = Binder.clearCallingIdentity();
11785            try {
11786                mActivityStarter.startConfirmCredentialIntent(intent);
11787            } finally {
11788                Binder.restoreCallingIdentity(ident);
11789            }
11790        }
11791    }
11792
11793    @Override
11794    public void stopAppSwitches() {
11795        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11796                != PackageManager.PERMISSION_GRANTED) {
11797            throw new SecurityException("viewquires permission "
11798                    + android.Manifest.permission.STOP_APP_SWITCHES);
11799        }
11800
11801        synchronized(this) {
11802            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11803                    + APP_SWITCH_DELAY_TIME;
11804            mDidAppSwitch = false;
11805            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11806            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11807            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11808        }
11809    }
11810
11811    public void resumeAppSwitches() {
11812        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11813                != PackageManager.PERMISSION_GRANTED) {
11814            throw new SecurityException("Requires permission "
11815                    + android.Manifest.permission.STOP_APP_SWITCHES);
11816        }
11817
11818        synchronized(this) {
11819            // Note that we don't execute any pending app switches... we will
11820            // let those wait until either the timeout, or the next start
11821            // activity request.
11822            mAppSwitchesAllowedTime = 0;
11823        }
11824    }
11825
11826    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11827            int callingPid, int callingUid, String name) {
11828        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11829            return true;
11830        }
11831
11832        int perm = checkComponentPermission(
11833                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11834                sourceUid, -1, true);
11835        if (perm == PackageManager.PERMISSION_GRANTED) {
11836            return true;
11837        }
11838
11839        // If the actual IPC caller is different from the logical source, then
11840        // also see if they are allowed to control app switches.
11841        if (callingUid != -1 && callingUid != sourceUid) {
11842            perm = checkComponentPermission(
11843                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11844                    callingUid, -1, true);
11845            if (perm == PackageManager.PERMISSION_GRANTED) {
11846                return true;
11847            }
11848        }
11849
11850        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11851        return false;
11852    }
11853
11854    public void setDebugApp(String packageName, boolean waitForDebugger,
11855            boolean persistent) {
11856        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11857                "setDebugApp()");
11858
11859        long ident = Binder.clearCallingIdentity();
11860        try {
11861            // Note that this is not really thread safe if there are multiple
11862            // callers into it at the same time, but that's not a situation we
11863            // care about.
11864            if (persistent) {
11865                final ContentResolver resolver = mContext.getContentResolver();
11866                Settings.Global.putString(
11867                    resolver, Settings.Global.DEBUG_APP,
11868                    packageName);
11869                Settings.Global.putInt(
11870                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11871                    waitForDebugger ? 1 : 0);
11872            }
11873
11874            synchronized (this) {
11875                if (!persistent) {
11876                    mOrigDebugApp = mDebugApp;
11877                    mOrigWaitForDebugger = mWaitForDebugger;
11878                }
11879                mDebugApp = packageName;
11880                mWaitForDebugger = waitForDebugger;
11881                mDebugTransient = !persistent;
11882                if (packageName != null) {
11883                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11884                            false, UserHandle.USER_ALL, "set debug app");
11885                }
11886            }
11887        } finally {
11888            Binder.restoreCallingIdentity(ident);
11889        }
11890    }
11891
11892    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11893        synchronized (this) {
11894            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11895            if (!isDebuggable) {
11896                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11897                    throw new SecurityException("Process not debuggable: " + app.packageName);
11898                }
11899            }
11900
11901            mTrackAllocationApp = processName;
11902        }
11903    }
11904
11905    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11906        synchronized (this) {
11907            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11908            if (!isDebuggable) {
11909                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11910                    throw new SecurityException("Process not debuggable: " + app.packageName);
11911                }
11912            }
11913            mProfileApp = processName;
11914            mProfileFile = profilerInfo.profileFile;
11915            if (mProfileFd != null) {
11916                try {
11917                    mProfileFd.close();
11918                } catch (IOException e) {
11919                }
11920                mProfileFd = null;
11921            }
11922            mProfileFd = profilerInfo.profileFd;
11923            mSamplingInterval = profilerInfo.samplingInterval;
11924            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11925            mProfileType = 0;
11926        }
11927    }
11928
11929    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11930        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11931        if (!isDebuggable) {
11932            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11933                throw new SecurityException("Process not debuggable: " + app.packageName);
11934            }
11935        }
11936        mNativeDebuggingApp = processName;
11937    }
11938
11939    @Override
11940    public void setAlwaysFinish(boolean enabled) {
11941        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11942                "setAlwaysFinish()");
11943
11944        long ident = Binder.clearCallingIdentity();
11945        try {
11946            Settings.Global.putInt(
11947                    mContext.getContentResolver(),
11948                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11949
11950            synchronized (this) {
11951                mAlwaysFinishActivities = enabled;
11952            }
11953        } finally {
11954            Binder.restoreCallingIdentity(ident);
11955        }
11956    }
11957
11958    @Override
11959    public void setLenientBackgroundCheck(boolean enabled) {
11960        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11961                "setLenientBackgroundCheck()");
11962
11963        long ident = Binder.clearCallingIdentity();
11964        try {
11965            Settings.Global.putInt(
11966                    mContext.getContentResolver(),
11967                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11968
11969            synchronized (this) {
11970                mLenientBackgroundCheck = enabled;
11971            }
11972        } finally {
11973            Binder.restoreCallingIdentity(ident);
11974        }
11975    }
11976
11977    @Override
11978    public void setActivityController(IActivityController controller, boolean imAMonkey) {
11979        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11980                "setActivityController()");
11981        synchronized (this) {
11982            mController = controller;
11983            mControllerIsAMonkey = imAMonkey;
11984            Watchdog.getInstance().setActivityController(controller);
11985        }
11986    }
11987
11988    @Override
11989    public void setUserIsMonkey(boolean userIsMonkey) {
11990        synchronized (this) {
11991            synchronized (mPidsSelfLocked) {
11992                final int callingPid = Binder.getCallingPid();
11993                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11994                if (precessRecord == null) {
11995                    throw new SecurityException("Unknown process: " + callingPid);
11996                }
11997                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11998                    throw new SecurityException("Only an instrumentation process "
11999                            + "with a UiAutomation can call setUserIsMonkey");
12000                }
12001            }
12002            mUserIsMonkey = userIsMonkey;
12003        }
12004    }
12005
12006    @Override
12007    public boolean isUserAMonkey() {
12008        synchronized (this) {
12009            // If there is a controller also implies the user is a monkey.
12010            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12011        }
12012    }
12013
12014    public void requestBugReport(int bugreportType) {
12015        String extraOptions = null;
12016        switch (bugreportType) {
12017            case ActivityManager.BUGREPORT_OPTION_FULL:
12018                // Default options.
12019                break;
12020            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12021                extraOptions = "bugreportplus";
12022                break;
12023            case ActivityManager.BUGREPORT_OPTION_REMOTE:
12024                extraOptions = "bugreportremote";
12025                break;
12026            case ActivityManager.BUGREPORT_OPTION_WEAR:
12027                extraOptions = "bugreportwear";
12028                break;
12029            default:
12030                throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12031                        + bugreportType);
12032        }
12033        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12034        if (extraOptions != null) {
12035            SystemProperties.set("dumpstate.options", extraOptions);
12036        }
12037        SystemProperties.set("ctl.start", "bugreport");
12038    }
12039
12040    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12041        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12042    }
12043
12044    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12045        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
12046            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12047        }
12048        return KEY_DISPATCHING_TIMEOUT;
12049    }
12050
12051    @Override
12052    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12053        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12054                != PackageManager.PERMISSION_GRANTED) {
12055            throw new SecurityException("Requires permission "
12056                    + android.Manifest.permission.FILTER_EVENTS);
12057        }
12058        ProcessRecord proc;
12059        long timeout;
12060        synchronized (this) {
12061            synchronized (mPidsSelfLocked) {
12062                proc = mPidsSelfLocked.get(pid);
12063            }
12064            timeout = getInputDispatchingTimeoutLocked(proc);
12065        }
12066
12067        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12068            return -1;
12069        }
12070
12071        return timeout;
12072    }
12073
12074    /**
12075     * Handle input dispatching timeouts.
12076     * Returns whether input dispatching should be aborted or not.
12077     */
12078    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12079            final ActivityRecord activity, final ActivityRecord parent,
12080            final boolean aboveSystem, String reason) {
12081        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12082                != PackageManager.PERMISSION_GRANTED) {
12083            throw new SecurityException("Requires permission "
12084                    + android.Manifest.permission.FILTER_EVENTS);
12085        }
12086
12087        final String annotation;
12088        if (reason == null) {
12089            annotation = "Input dispatching timed out";
12090        } else {
12091            annotation = "Input dispatching timed out (" + reason + ")";
12092        }
12093
12094        if (proc != null) {
12095            synchronized (this) {
12096                if (proc.debugging) {
12097                    return false;
12098                }
12099
12100                if (mDidDexOpt) {
12101                    // Give more time since we were dexopting.
12102                    mDidDexOpt = false;
12103                    return false;
12104                }
12105
12106                if (proc.instrumentationClass != null) {
12107                    Bundle info = new Bundle();
12108                    info.putString("shortMsg", "keyDispatchingTimedOut");
12109                    info.putString("longMsg", annotation);
12110                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12111                    return true;
12112                }
12113            }
12114            mHandler.post(new Runnable() {
12115                @Override
12116                public void run() {
12117                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12118                }
12119            });
12120        }
12121
12122        return true;
12123    }
12124
12125    @Override
12126    public Bundle getAssistContextExtras(int requestType) {
12127        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12128                null, null, true /* focused */, true /* newSessionId */,
12129                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12130        if (pae == null) {
12131            return null;
12132        }
12133        synchronized (pae) {
12134            while (!pae.haveResult) {
12135                try {
12136                    pae.wait();
12137                } catch (InterruptedException e) {
12138                }
12139            }
12140        }
12141        synchronized (this) {
12142            buildAssistBundleLocked(pae, pae.result);
12143            mPendingAssistExtras.remove(pae);
12144            mUiHandler.removeCallbacks(pae);
12145        }
12146        return pae.extras;
12147    }
12148
12149    @Override
12150    public boolean isAssistDataAllowedOnCurrentActivity() {
12151        int userId;
12152        synchronized (this) {
12153            userId = mUserController.getCurrentUserIdLocked();
12154            ActivityRecord activity = getFocusedStack().topActivity();
12155            if (activity == null) {
12156                return false;
12157            }
12158            userId = activity.userId;
12159        }
12160        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12161                Context.DEVICE_POLICY_SERVICE);
12162        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12163    }
12164
12165    @Override
12166    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12167        long ident = Binder.clearCallingIdentity();
12168        try {
12169            synchronized (this) {
12170                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12171                ActivityRecord top = getFocusedStack().topActivity();
12172                if (top != caller) {
12173                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12174                            + " is not current top " + top);
12175                    return false;
12176                }
12177                if (!top.nowVisible) {
12178                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12179                            + " is not visible");
12180                    return false;
12181                }
12182            }
12183            AssistUtils utils = new AssistUtils(mContext);
12184            return utils.showSessionForActiveService(args,
12185                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12186        } finally {
12187            Binder.restoreCallingIdentity(ident);
12188        }
12189    }
12190
12191    @Override
12192    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12193            Bundle receiverExtras,
12194            IBinder activityToken, boolean focused, boolean newSessionId) {
12195        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12196                activityToken, focused, newSessionId,
12197                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12198                != null;
12199    }
12200
12201    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12202            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12203            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12204        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12205                "enqueueAssistContext()");
12206        synchronized (this) {
12207            ActivityRecord activity = getFocusedStack().topActivity();
12208            if (activity == null) {
12209                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12210                return null;
12211            }
12212            if (activity.app == null || activity.app.thread == null) {
12213                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12214                return null;
12215            }
12216            if (focused) {
12217                if (activityToken != null) {
12218                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12219                    if (activity != caller) {
12220                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12221                                + " is not current top " + activity);
12222                        return null;
12223                    }
12224                }
12225            } else {
12226                activity = ActivityRecord.forTokenLocked(activityToken);
12227                if (activity == null) {
12228                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12229                            + " couldn't be found");
12230                    return null;
12231                }
12232            }
12233
12234            PendingAssistExtras pae;
12235            Bundle extras = new Bundle();
12236            if (args != null) {
12237                extras.putAll(args);
12238            }
12239            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12240            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12241            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12242                    userHandle);
12243            // Increment the sessionId if necessary
12244            if (newSessionId) {
12245                mViSessionId++;
12246            }
12247            try {
12248                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12249                        requestType, mViSessionId);
12250                mPendingAssistExtras.add(pae);
12251                mUiHandler.postDelayed(pae, timeout);
12252            } catch (RemoteException e) {
12253                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12254                return null;
12255            }
12256            return pae;
12257        }
12258    }
12259
12260    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12261        IResultReceiver receiver;
12262        synchronized (this) {
12263            mPendingAssistExtras.remove(pae);
12264            receiver = pae.receiver;
12265        }
12266        if (receiver != null) {
12267            // Caller wants result sent back to them.
12268            Bundle sendBundle = new Bundle();
12269            // At least return the receiver extras
12270            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12271                    pae.receiverExtras);
12272            try {
12273                pae.receiver.send(0, sendBundle);
12274            } catch (RemoteException e) {
12275            }
12276        }
12277    }
12278
12279    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12280        if (result != null) {
12281            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12282        }
12283        if (pae.hint != null) {
12284            pae.extras.putBoolean(pae.hint, true);
12285        }
12286    }
12287
12288    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12289            AssistContent content, Uri referrer) {
12290        PendingAssistExtras pae = (PendingAssistExtras)token;
12291        synchronized (pae) {
12292            pae.result = extras;
12293            pae.structure = structure;
12294            pae.content = content;
12295            if (referrer != null) {
12296                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12297            }
12298            pae.haveResult = true;
12299            pae.notifyAll();
12300            if (pae.intent == null && pae.receiver == null) {
12301                // Caller is just waiting for the result.
12302                return;
12303            }
12304        }
12305
12306        // We are now ready to launch the assist activity.
12307        IResultReceiver sendReceiver = null;
12308        Bundle sendBundle = null;
12309        synchronized (this) {
12310            buildAssistBundleLocked(pae, extras);
12311            boolean exists = mPendingAssistExtras.remove(pae);
12312            mUiHandler.removeCallbacks(pae);
12313            if (!exists) {
12314                // Timed out.
12315                return;
12316            }
12317            if ((sendReceiver=pae.receiver) != null) {
12318                // Caller wants result sent back to them.
12319                sendBundle = new Bundle();
12320                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12321                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12322                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12323                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12324                        pae.receiverExtras);
12325            }
12326        }
12327        if (sendReceiver != null) {
12328            try {
12329                sendReceiver.send(0, sendBundle);
12330            } catch (RemoteException e) {
12331            }
12332            return;
12333        }
12334
12335        long ident = Binder.clearCallingIdentity();
12336        try {
12337            pae.intent.replaceExtras(pae.extras);
12338            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12339                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12340                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12341            closeSystemDialogs("assist");
12342            try {
12343                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12344            } catch (ActivityNotFoundException e) {
12345                Slog.w(TAG, "No activity to handle assist action.", e);
12346            }
12347        } finally {
12348            Binder.restoreCallingIdentity(ident);
12349        }
12350    }
12351
12352    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12353            Bundle args) {
12354        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12355                true /* focused */, true /* newSessionId */,
12356                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12357    }
12358
12359    public void registerProcessObserver(IProcessObserver observer) {
12360        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12361                "registerProcessObserver()");
12362        synchronized (this) {
12363            mProcessObservers.register(observer);
12364        }
12365    }
12366
12367    @Override
12368    public void unregisterProcessObserver(IProcessObserver observer) {
12369        synchronized (this) {
12370            mProcessObservers.unregister(observer);
12371        }
12372    }
12373
12374    @Override
12375    public void registerUidObserver(IUidObserver observer, int which) {
12376        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12377                "registerUidObserver()");
12378        synchronized (this) {
12379            mUidObservers.register(observer, which);
12380        }
12381    }
12382
12383    @Override
12384    public void unregisterUidObserver(IUidObserver observer) {
12385        synchronized (this) {
12386            mUidObservers.unregister(observer);
12387        }
12388    }
12389
12390    @Override
12391    public boolean convertFromTranslucent(IBinder token) {
12392        final long origId = Binder.clearCallingIdentity();
12393        try {
12394            synchronized (this) {
12395                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12396                if (r == null) {
12397                    return false;
12398                }
12399                final boolean translucentChanged = r.changeWindowTranslucency(true);
12400                if (translucentChanged) {
12401                    r.getStack().releaseBackgroundResources(r);
12402                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12403                }
12404                mWindowManager.setAppFullscreen(token, true);
12405                return translucentChanged;
12406            }
12407        } finally {
12408            Binder.restoreCallingIdentity(origId);
12409        }
12410    }
12411
12412    @Override
12413    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12414        final long origId = Binder.clearCallingIdentity();
12415        try {
12416            synchronized (this) {
12417                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12418                if (r == null) {
12419                    return false;
12420                }
12421                int index = r.task.mActivities.lastIndexOf(r);
12422                if (index > 0) {
12423                    ActivityRecord under = r.task.mActivities.get(index - 1);
12424                    under.returningOptions = options;
12425                }
12426                final boolean translucentChanged = r.changeWindowTranslucency(false);
12427                if (translucentChanged) {
12428                    r.getStack().convertActivityToTranslucent(r);
12429                }
12430                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12431                mWindowManager.setAppFullscreen(token, false);
12432                return translucentChanged;
12433            }
12434        } finally {
12435            Binder.restoreCallingIdentity(origId);
12436        }
12437    }
12438
12439    @Override
12440    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12441        final long origId = Binder.clearCallingIdentity();
12442        try {
12443            synchronized (this) {
12444                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12445                if (r != null) {
12446                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12447                }
12448            }
12449            return false;
12450        } finally {
12451            Binder.restoreCallingIdentity(origId);
12452        }
12453    }
12454
12455    @Override
12456    public boolean isBackgroundVisibleBehind(IBinder token) {
12457        final long origId = Binder.clearCallingIdentity();
12458        try {
12459            synchronized (this) {
12460                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12461                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12462                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12463                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12464                return visible;
12465            }
12466        } finally {
12467            Binder.restoreCallingIdentity(origId);
12468        }
12469    }
12470
12471    @Override
12472    public ActivityOptions getActivityOptions(IBinder token) {
12473        final long origId = Binder.clearCallingIdentity();
12474        try {
12475            synchronized (this) {
12476                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12477                if (r != null) {
12478                    final ActivityOptions activityOptions = r.pendingOptions;
12479                    r.pendingOptions = null;
12480                    return activityOptions;
12481                }
12482                return null;
12483            }
12484        } finally {
12485            Binder.restoreCallingIdentity(origId);
12486        }
12487    }
12488
12489    @Override
12490    public void setImmersive(IBinder token, boolean immersive) {
12491        synchronized(this) {
12492            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12493            if (r == null) {
12494                throw new IllegalArgumentException();
12495            }
12496            r.immersive = immersive;
12497
12498            // update associated state if we're frontmost
12499            if (r == mStackSupervisor.getResumedActivityLocked()) {
12500                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12501                applyUpdateLockStateLocked(r);
12502            }
12503        }
12504    }
12505
12506    @Override
12507    public boolean isImmersive(IBinder token) {
12508        synchronized (this) {
12509            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12510            if (r == null) {
12511                throw new IllegalArgumentException();
12512            }
12513            return r.immersive;
12514        }
12515    }
12516
12517    public void setVrThread(int tid) {
12518        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12519            throw new UnsupportedOperationException("VR mode not supported on this device!");
12520        }
12521
12522        synchronized (this) {
12523            ProcessRecord proc;
12524            synchronized (mPidsSelfLocked) {
12525                final int pid = Binder.getCallingPid();
12526                proc = mPidsSelfLocked.get(pid);
12527
12528                if (proc != null && mInVrMode && tid >= 0) {
12529                    // ensure the tid belongs to the process
12530                    if (!Process.isThreadInProcess(pid, tid)) {
12531                        throw new IllegalArgumentException("VR thread does not belong to process");
12532                    }
12533
12534                    // reset existing VR thread to CFS if this thread still exists and belongs to
12535                    // the calling process
12536                    if (proc.vrThreadTid != 0
12537                            && Process.isThreadInProcess(pid, proc.vrThreadTid)) {
12538                        try {
12539                            Process.setThreadScheduler(proc.vrThreadTid, Process.SCHED_OTHER, 0);
12540                        } catch (IllegalArgumentException e) {
12541                            // Ignore this.  Only occurs in race condition where previous VR thread
12542                            // was destroyed during this method call.
12543                        }
12544                    }
12545
12546                    proc.vrThreadTid = tid;
12547
12548                    // promote to FIFO now if the tid is non-zero
12549                    try {
12550                        if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
12551                            proc.vrThreadTid > 0) {
12552                            Process.setThreadScheduler(proc.vrThreadTid,
12553                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12554                        }
12555                    } catch (IllegalArgumentException e) {
12556                        Slog.e(TAG, "Failed to set scheduling policy, thread does"
12557                               + " not exist:\n" + e);
12558                    }
12559                }
12560            }
12561        }
12562    }
12563
12564    @Override
12565    public void setRenderThread(int tid) {
12566        synchronized (this) {
12567            ProcessRecord proc;
12568            synchronized (mPidsSelfLocked) {
12569                int pid = Binder.getCallingPid();
12570                proc = mPidsSelfLocked.get(pid);
12571                if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
12572                    // ensure the tid belongs to the process
12573                    if (!Process.isThreadInProcess(pid, tid)) {
12574                        throw new IllegalArgumentException(
12575                            "Render thread does not belong to process");
12576                    }
12577                    proc.renderThreadTid = tid;
12578                    if (DEBUG_OOM_ADJ) {
12579                        Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
12580                    }
12581                    // promote to FIFO now
12582                    if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
12583                        if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
12584                        if (mUseFifoUiScheduling) {
12585                            Process.setThreadScheduler(proc.renderThreadTid,
12586                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12587                        } else {
12588                            Process.setThreadPriority(proc.renderThreadTid, -10);
12589                        }
12590                    }
12591                } else {
12592                    if (DEBUG_OOM_ADJ) {
12593                        Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
12594                               "PID: " + pid + ", TID: " + tid + " FIFO: " +
12595                               mUseFifoUiScheduling);
12596                    }
12597                }
12598            }
12599        }
12600    }
12601
12602    @Override
12603    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12604        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12605            throw new UnsupportedOperationException("VR mode not supported on this device!");
12606        }
12607
12608        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12609
12610        ActivityRecord r;
12611        synchronized (this) {
12612            r = ActivityRecord.isInStackLocked(token);
12613        }
12614
12615        if (r == null) {
12616            throw new IllegalArgumentException();
12617        }
12618
12619        int err;
12620        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12621                VrManagerInternal.NO_ERROR) {
12622            return err;
12623        }
12624
12625        synchronized(this) {
12626            r.requestedVrComponent = (enabled) ? packageName : null;
12627
12628            // Update associated state if this activity is currently focused
12629            if (r == mStackSupervisor.getResumedActivityLocked()) {
12630                applyUpdateVrModeLocked(r);
12631            }
12632            return 0;
12633        }
12634    }
12635
12636    @Override
12637    public boolean isVrModePackageEnabled(ComponentName packageName) {
12638        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12639            throw new UnsupportedOperationException("VR mode not supported on this device!");
12640        }
12641
12642        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12643
12644        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12645                VrManagerInternal.NO_ERROR;
12646    }
12647
12648    public boolean isTopActivityImmersive() {
12649        enforceNotIsolatedCaller("startActivity");
12650        synchronized (this) {
12651            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12652            return (r != null) ? r.immersive : false;
12653        }
12654    }
12655
12656    @Override
12657    public boolean isTopOfTask(IBinder token) {
12658        synchronized (this) {
12659            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12660            if (r == null) {
12661                throw new IllegalArgumentException();
12662            }
12663            return r.task.getTopActivity() == r;
12664        }
12665    }
12666
12667    @Override
12668    public void setHasTopUi(boolean hasTopUi) throws RemoteException {
12669        if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
12670            String msg = "Permission Denial: setHasTopUi() from pid="
12671                    + Binder.getCallingPid()
12672                    + ", uid=" + Binder.getCallingUid()
12673                    + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
12674            Slog.w(TAG, msg);
12675            throw new SecurityException(msg);
12676        }
12677        final int pid = Binder.getCallingPid();
12678        final long origId = Binder.clearCallingIdentity();
12679        try {
12680            synchronized (this) {
12681                boolean changed = false;
12682                ProcessRecord pr;
12683                synchronized (mPidsSelfLocked) {
12684                    pr = mPidsSelfLocked.get(pid);
12685                    if (pr == null) {
12686                        Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
12687                        return;
12688                    }
12689                    if (pr.hasTopUi != hasTopUi) {
12690                        Slog.i(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
12691                        pr.hasTopUi = hasTopUi;
12692                        changed = true;
12693                    }
12694                }
12695                if (changed) {
12696                    updateOomAdjLocked(pr);
12697                }
12698            }
12699        } finally {
12700            Binder.restoreCallingIdentity(origId);
12701        }
12702    }
12703
12704    public final void enterSafeMode() {
12705        synchronized(this) {
12706            // It only makes sense to do this before the system is ready
12707            // and started launching other packages.
12708            if (!mSystemReady) {
12709                try {
12710                    AppGlobals.getPackageManager().enterSafeMode();
12711                } catch (RemoteException e) {
12712                }
12713            }
12714
12715            mSafeMode = true;
12716        }
12717    }
12718
12719    public final void showSafeModeOverlay() {
12720        View v = LayoutInflater.from(mContext).inflate(
12721                com.android.internal.R.layout.safe_mode, null);
12722        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12723        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12724        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12725        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12726        lp.gravity = Gravity.BOTTOM | Gravity.START;
12727        lp.format = v.getBackground().getOpacity();
12728        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12729                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12730        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12731        ((WindowManager)mContext.getSystemService(
12732                Context.WINDOW_SERVICE)).addView(v, lp);
12733    }
12734
12735    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12736        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12737            return;
12738        }
12739        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12740        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12741        synchronized (stats) {
12742            if (mBatteryStatsService.isOnBattery()) {
12743                mBatteryStatsService.enforceCallingPermission();
12744                int MY_UID = Binder.getCallingUid();
12745                final int uid;
12746                if (sender == null) {
12747                    uid = sourceUid;
12748                } else {
12749                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12750                }
12751                BatteryStatsImpl.Uid.Pkg pkg =
12752                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12753                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12754                pkg.noteWakeupAlarmLocked(tag);
12755            }
12756        }
12757    }
12758
12759    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12760        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12761            return;
12762        }
12763        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12764        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12765        synchronized (stats) {
12766            mBatteryStatsService.enforceCallingPermission();
12767            int MY_UID = Binder.getCallingUid();
12768            final int uid;
12769            if (sender == null) {
12770                uid = sourceUid;
12771            } else {
12772                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12773            }
12774            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12775        }
12776    }
12777
12778    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12779        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12780            return;
12781        }
12782        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12783        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12784        synchronized (stats) {
12785            mBatteryStatsService.enforceCallingPermission();
12786            int MY_UID = Binder.getCallingUid();
12787            final int uid;
12788            if (sender == null) {
12789                uid = sourceUid;
12790            } else {
12791                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12792            }
12793            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12794        }
12795    }
12796
12797    public boolean killPids(int[] pids, String pReason, boolean secure) {
12798        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12799            throw new SecurityException("killPids only available to the system");
12800        }
12801        String reason = (pReason == null) ? "Unknown" : pReason;
12802        // XXX Note: don't acquire main activity lock here, because the window
12803        // manager calls in with its locks held.
12804
12805        boolean killed = false;
12806        synchronized (mPidsSelfLocked) {
12807            int worstType = 0;
12808            for (int i=0; i<pids.length; i++) {
12809                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12810                if (proc != null) {
12811                    int type = proc.setAdj;
12812                    if (type > worstType) {
12813                        worstType = type;
12814                    }
12815                }
12816            }
12817
12818            // If the worst oom_adj is somewhere in the cached proc LRU range,
12819            // then constrain it so we will kill all cached procs.
12820            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12821                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12822                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12823            }
12824
12825            // If this is not a secure call, don't let it kill processes that
12826            // are important.
12827            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12828                worstType = ProcessList.SERVICE_ADJ;
12829            }
12830
12831            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12832            for (int i=0; i<pids.length; i++) {
12833                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12834                if (proc == null) {
12835                    continue;
12836                }
12837                int adj = proc.setAdj;
12838                if (adj >= worstType && !proc.killedByAm) {
12839                    proc.kill(reason, true);
12840                    killed = true;
12841                }
12842            }
12843        }
12844        return killed;
12845    }
12846
12847    @Override
12848    public void killUid(int appId, int userId, String reason) {
12849        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12850        synchronized (this) {
12851            final long identity = Binder.clearCallingIdentity();
12852            try {
12853                killPackageProcessesLocked(null, appId, userId,
12854                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12855                        reason != null ? reason : "kill uid");
12856            } finally {
12857                Binder.restoreCallingIdentity(identity);
12858            }
12859        }
12860    }
12861
12862    @Override
12863    public boolean killProcessesBelowForeground(String reason) {
12864        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12865            throw new SecurityException("killProcessesBelowForeground() only available to system");
12866        }
12867
12868        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12869    }
12870
12871    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12872        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12873            throw new SecurityException("killProcessesBelowAdj() only available to system");
12874        }
12875
12876        boolean killed = false;
12877        synchronized (mPidsSelfLocked) {
12878            final int size = mPidsSelfLocked.size();
12879            for (int i = 0; i < size; i++) {
12880                final int pid = mPidsSelfLocked.keyAt(i);
12881                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12882                if (proc == null) continue;
12883
12884                final int adj = proc.setAdj;
12885                if (adj > belowAdj && !proc.killedByAm) {
12886                    proc.kill(reason, true);
12887                    killed = true;
12888                }
12889            }
12890        }
12891        return killed;
12892    }
12893
12894    @Override
12895    public void hang(final IBinder who, boolean allowRestart) {
12896        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12897                != PackageManager.PERMISSION_GRANTED) {
12898            throw new SecurityException("Requires permission "
12899                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12900        }
12901
12902        final IBinder.DeathRecipient death = new DeathRecipient() {
12903            @Override
12904            public void binderDied() {
12905                synchronized (this) {
12906                    notifyAll();
12907                }
12908            }
12909        };
12910
12911        try {
12912            who.linkToDeath(death, 0);
12913        } catch (RemoteException e) {
12914            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12915            return;
12916        }
12917
12918        synchronized (this) {
12919            Watchdog.getInstance().setAllowRestart(allowRestart);
12920            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12921            synchronized (death) {
12922                while (who.isBinderAlive()) {
12923                    try {
12924                        death.wait();
12925                    } catch (InterruptedException e) {
12926                    }
12927                }
12928            }
12929            Watchdog.getInstance().setAllowRestart(true);
12930        }
12931    }
12932
12933    @Override
12934    public void restart() {
12935        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12936                != PackageManager.PERMISSION_GRANTED) {
12937            throw new SecurityException("Requires permission "
12938                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12939        }
12940
12941        Log.i(TAG, "Sending shutdown broadcast...");
12942
12943        BroadcastReceiver br = new BroadcastReceiver() {
12944            @Override public void onReceive(Context context, Intent intent) {
12945                // Now the broadcast is done, finish up the low-level shutdown.
12946                Log.i(TAG, "Shutting down activity manager...");
12947                shutdown(10000);
12948                Log.i(TAG, "Shutdown complete, restarting!");
12949                Process.killProcess(Process.myPid());
12950                System.exit(10);
12951            }
12952        };
12953
12954        // First send the high-level shut down broadcast.
12955        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12956        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12957        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12958        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12959        mContext.sendOrderedBroadcastAsUser(intent,
12960                UserHandle.ALL, null, br, mHandler, 0, null, null);
12961        */
12962        br.onReceive(mContext, intent);
12963    }
12964
12965    private long getLowRamTimeSinceIdle(long now) {
12966        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12967    }
12968
12969    @Override
12970    public void performIdleMaintenance() {
12971        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12972                != PackageManager.PERMISSION_GRANTED) {
12973            throw new SecurityException("Requires permission "
12974                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12975        }
12976
12977        synchronized (this) {
12978            final long now = SystemClock.uptimeMillis();
12979            final long timeSinceLastIdle = now - mLastIdleTime;
12980            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12981            mLastIdleTime = now;
12982            mLowRamTimeSinceLastIdle = 0;
12983            if (mLowRamStartTime != 0) {
12984                mLowRamStartTime = now;
12985            }
12986
12987            StringBuilder sb = new StringBuilder(128);
12988            sb.append("Idle maintenance over ");
12989            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12990            sb.append(" low RAM for ");
12991            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12992            Slog.i(TAG, sb.toString());
12993
12994            // If at least 1/3 of our time since the last idle period has been spent
12995            // with RAM low, then we want to kill processes.
12996            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12997
12998            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12999                ProcessRecord proc = mLruProcesses.get(i);
13000                if (proc.notCachedSinceIdle) {
13001                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
13002                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
13003                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
13004                        if (doKilling && proc.initialIdlePss != 0
13005                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
13006                            sb = new StringBuilder(128);
13007                            sb.append("Kill");
13008                            sb.append(proc.processName);
13009                            sb.append(" in idle maint: pss=");
13010                            sb.append(proc.lastPss);
13011                            sb.append(", swapPss=");
13012                            sb.append(proc.lastSwapPss);
13013                            sb.append(", initialPss=");
13014                            sb.append(proc.initialIdlePss);
13015                            sb.append(", period=");
13016                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13017                            sb.append(", lowRamPeriod=");
13018                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13019                            Slog.wtfQuiet(TAG, sb.toString());
13020                            proc.kill("idle maint (pss " + proc.lastPss
13021                                    + " from " + proc.initialIdlePss + ")", true);
13022                        }
13023                    }
13024                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
13025                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
13026                    proc.notCachedSinceIdle = true;
13027                    proc.initialIdlePss = 0;
13028                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
13029                            mTestPssMode, isSleepingLocked(), now);
13030                }
13031            }
13032
13033            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
13034            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
13035        }
13036    }
13037
13038    @Override
13039    public void sendIdleJobTrigger() {
13040        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13041                != PackageManager.PERMISSION_GRANTED) {
13042            throw new SecurityException("Requires permission "
13043                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13044        }
13045
13046        final long ident = Binder.clearCallingIdentity();
13047        try {
13048            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
13049                    .setPackage("android")
13050                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13051            broadcastIntent(null, intent, null, null, 0, null, null, null,
13052                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
13053        } finally {
13054            Binder.restoreCallingIdentity(ident);
13055        }
13056    }
13057
13058    private void retrieveSettings() {
13059        final ContentResolver resolver = mContext.getContentResolver();
13060        final boolean freeformWindowManagement =
13061                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
13062                        || Settings.Global.getInt(
13063                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
13064        final boolean supportsPictureInPicture =
13065                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
13066
13067        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
13068        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
13069        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
13070        final boolean alwaysFinishActivities =
13071                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
13072        final boolean lenientBackgroundCheck =
13073                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
13074        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
13075        final boolean forceResizable = Settings.Global.getInt(
13076                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
13077        final boolean supportsLeanbackOnly =
13078                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
13079
13080        // Transfer any global setting for forcing RTL layout, into a System Property
13081        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
13082
13083        final Configuration configuration = new Configuration();
13084        Settings.System.getConfiguration(resolver, configuration);
13085        if (forceRtl) {
13086            // This will take care of setting the correct layout direction flags
13087            configuration.setLayoutDirection(configuration.locale);
13088        }
13089
13090        synchronized (this) {
13091            mDebugApp = mOrigDebugApp = debugApp;
13092            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
13093            mAlwaysFinishActivities = alwaysFinishActivities;
13094            mLenientBackgroundCheck = lenientBackgroundCheck;
13095            mSupportsLeanbackOnly = supportsLeanbackOnly;
13096            mForceResizableActivities = forceResizable;
13097            mWindowManager.setForceResizableTasks(mForceResizableActivities);
13098            if (supportsMultiWindow || forceResizable) {
13099                mSupportsMultiWindow = true;
13100                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
13101                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
13102            } else {
13103                mSupportsMultiWindow = false;
13104                mSupportsFreeformWindowManagement = false;
13105                mSupportsPictureInPicture = false;
13106            }
13107            // This happens before any activities are started, so we can change global configuration
13108            // in-place.
13109            updateConfigurationLocked(configuration, null, true);
13110            final Configuration globalConfig = getGlobalConfiguration();
13111            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
13112
13113            // Load resources only after the current configuration has been set.
13114            final Resources res = mContext.getResources();
13115            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
13116            mThumbnailWidth = res.getDimensionPixelSize(
13117                    com.android.internal.R.dimen.thumbnail_width);
13118            mThumbnailHeight = res.getDimensionPixelSize(
13119                    com.android.internal.R.dimen.thumbnail_height);
13120            mDefaultPinnedStackSizeDp = Size.parseSize(res.getString(
13121                    com.android.internal.R.string.config_defaultPictureInPictureSize));
13122            mDefaultPinnedStackScreenEdgeInsetsDp = Size.parseSize(res.getString(
13123                    com.android.internal.R.string.config_defaultPictureInPictureScreenEdgeInsets));
13124            mDefaultPinnedStackGravity = res.getInteger(
13125                    com.android.internal.R.integer.config_defaultPictureInPictureGravity);
13126            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
13127                    com.android.internal.R.string.config_appsNotReportingCrashes));
13128            mUserController.mUserSwitchUiEnabled = !res.getBoolean(
13129                    com.android.internal.R.bool.config_customUserSwitchUi);
13130            if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
13131                mFullscreenThumbnailScale = (float) res
13132                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
13133                    (float) globalConfig.screenWidthDp;
13134            } else {
13135                mFullscreenThumbnailScale = res.getFraction(
13136                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13137            }
13138        }
13139    }
13140
13141    public boolean testIsSystemReady() {
13142        // no need to synchronize(this) just to read & return the value
13143        return mSystemReady;
13144    }
13145
13146    public void systemReady(final Runnable goingCallback) {
13147        synchronized(this) {
13148            if (mSystemReady) {
13149                // If we're done calling all the receivers, run the next "boot phase" passed in
13150                // by the SystemServer
13151                if (goingCallback != null) {
13152                    goingCallback.run();
13153                }
13154                return;
13155            }
13156
13157            mLocalDeviceIdleController
13158                    = LocalServices.getService(DeviceIdleController.LocalService.class);
13159
13160            // Make sure we have the current profile info, since it is needed for security checks.
13161            mUserController.onSystemReady();
13162            mRecentTasks.onSystemReadyLocked();
13163            mAppOpsService.systemReady();
13164            mSystemReady = true;
13165        }
13166
13167        ArrayList<ProcessRecord> procsToKill = null;
13168        synchronized(mPidsSelfLocked) {
13169            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13170                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13171                if (!isAllowedWhileBooting(proc.info)){
13172                    if (procsToKill == null) {
13173                        procsToKill = new ArrayList<ProcessRecord>();
13174                    }
13175                    procsToKill.add(proc);
13176                }
13177            }
13178        }
13179
13180        synchronized(this) {
13181            if (procsToKill != null) {
13182                for (int i=procsToKill.size()-1; i>=0; i--) {
13183                    ProcessRecord proc = procsToKill.get(i);
13184                    Slog.i(TAG, "Removing system update proc: " + proc);
13185                    removeProcessLocked(proc, true, false, "system update done");
13186                }
13187            }
13188
13189            // Now that we have cleaned up any update processes, we
13190            // are ready to start launching real processes and know that
13191            // we won't trample on them any more.
13192            mProcessesReady = true;
13193        }
13194
13195        Slog.i(TAG, "System now ready");
13196        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13197            SystemClock.uptimeMillis());
13198
13199        synchronized(this) {
13200            // Make sure we have no pre-ready processes sitting around.
13201
13202            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13203                ResolveInfo ri = mContext.getPackageManager()
13204                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13205                                STOCK_PM_FLAGS);
13206                CharSequence errorMsg = null;
13207                if (ri != null) {
13208                    ActivityInfo ai = ri.activityInfo;
13209                    ApplicationInfo app = ai.applicationInfo;
13210                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13211                        mTopAction = Intent.ACTION_FACTORY_TEST;
13212                        mTopData = null;
13213                        mTopComponent = new ComponentName(app.packageName,
13214                                ai.name);
13215                    } else {
13216                        errorMsg = mContext.getResources().getText(
13217                                com.android.internal.R.string.factorytest_not_system);
13218                    }
13219                } else {
13220                    errorMsg = mContext.getResources().getText(
13221                            com.android.internal.R.string.factorytest_no_action);
13222                }
13223                if (errorMsg != null) {
13224                    mTopAction = null;
13225                    mTopData = null;
13226                    mTopComponent = null;
13227                    Message msg = Message.obtain();
13228                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13229                    msg.getData().putCharSequence("msg", errorMsg);
13230                    mUiHandler.sendMessage(msg);
13231                }
13232            }
13233        }
13234
13235        retrieveSettings();
13236        final int currentUserId;
13237        synchronized (this) {
13238            currentUserId = mUserController.getCurrentUserIdLocked();
13239            readGrantedUriPermissionsLocked();
13240        }
13241
13242        if (goingCallback != null) goingCallback.run();
13243
13244        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13245                Integer.toString(currentUserId), currentUserId);
13246        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13247                Integer.toString(currentUserId), currentUserId);
13248        mSystemServiceManager.startUser(currentUserId);
13249
13250        synchronized (this) {
13251            // Only start up encryption-aware persistent apps; once user is
13252            // unlocked we'll come back around and start unaware apps
13253            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13254
13255            // Start up initial activity.
13256            mBooting = true;
13257            // Enable home activity for system user, so that the system can always boot. We don't
13258            // do this when the system user is not setup since the setup wizard should be the one
13259            // to handle home activity in this case.
13260            if (UserManager.isSplitSystemUser() &&
13261                    Settings.Secure.getInt(mContext.getContentResolver(),
13262                         Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
13263                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13264                try {
13265                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13266                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13267                            UserHandle.USER_SYSTEM);
13268                } catch (RemoteException e) {
13269                    throw e.rethrowAsRuntimeException();
13270                }
13271            }
13272            startHomeActivityLocked(currentUserId, "systemReady");
13273
13274            try {
13275                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13276                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13277                            + " data partition or your device will be unstable.");
13278                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13279                }
13280            } catch (RemoteException e) {
13281            }
13282
13283            if (!Build.isBuildConsistent()) {
13284                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13285                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13286            }
13287
13288            long ident = Binder.clearCallingIdentity();
13289            try {
13290                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13291                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13292                        | Intent.FLAG_RECEIVER_FOREGROUND);
13293                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13294                broadcastIntentLocked(null, null, intent,
13295                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13296                        null, false, false, MY_PID, Process.SYSTEM_UID,
13297                        currentUserId);
13298                intent = new Intent(Intent.ACTION_USER_STARTING);
13299                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13300                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13301                broadcastIntentLocked(null, null, intent,
13302                        null, new IIntentReceiver.Stub() {
13303                            @Override
13304                            public void performReceive(Intent intent, int resultCode, String data,
13305                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13306                                    throws RemoteException {
13307                            }
13308                        }, 0, null, null,
13309                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13310                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13311            } catch (Throwable t) {
13312                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13313            } finally {
13314                Binder.restoreCallingIdentity(ident);
13315            }
13316            mStackSupervisor.resumeFocusedStackTopActivityLocked();
13317            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13318        }
13319    }
13320
13321    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13322        synchronized (this) {
13323            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13324        }
13325    }
13326
13327    void skipCurrentReceiverLocked(ProcessRecord app) {
13328        for (BroadcastQueue queue : mBroadcastQueues) {
13329            queue.skipCurrentReceiverLocked(app);
13330        }
13331    }
13332
13333    /**
13334     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13335     * The application process will exit immediately after this call returns.
13336     * @param app object of the crashing app, null for the system server
13337     * @param crashInfo describing the exception
13338     */
13339    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13340        ProcessRecord r = findAppProcess(app, "Crash");
13341        final String processName = app == null ? "system_server"
13342                : (r == null ? "unknown" : r.processName);
13343
13344        handleApplicationCrashInner("crash", r, processName, crashInfo);
13345    }
13346
13347    /* Native crash reporting uses this inner version because it needs to be somewhat
13348     * decoupled from the AM-managed cleanup lifecycle
13349     */
13350    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13351            ApplicationErrorReport.CrashInfo crashInfo) {
13352        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13353                UserHandle.getUserId(Binder.getCallingUid()), processName,
13354                r == null ? -1 : r.info.flags,
13355                crashInfo.exceptionClassName,
13356                crashInfo.exceptionMessage,
13357                crashInfo.throwFileName,
13358                crashInfo.throwLineNumber);
13359
13360        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13361
13362        mAppErrors.crashApplication(r, crashInfo);
13363    }
13364
13365    public void handleApplicationStrictModeViolation(
13366            IBinder app,
13367            int violationMask,
13368            StrictMode.ViolationInfo info) {
13369        ProcessRecord r = findAppProcess(app, "StrictMode");
13370        if (r == null) {
13371            return;
13372        }
13373
13374        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13375            Integer stackFingerprint = info.hashCode();
13376            boolean logIt = true;
13377            synchronized (mAlreadyLoggedViolatedStacks) {
13378                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13379                    logIt = false;
13380                    // TODO: sub-sample into EventLog for these, with
13381                    // the info.durationMillis?  Then we'd get
13382                    // the relative pain numbers, without logging all
13383                    // the stack traces repeatedly.  We'd want to do
13384                    // likewise in the client code, which also does
13385                    // dup suppression, before the Binder call.
13386                } else {
13387                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13388                        mAlreadyLoggedViolatedStacks.clear();
13389                    }
13390                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13391                }
13392            }
13393            if (logIt) {
13394                logStrictModeViolationToDropBox(r, info);
13395            }
13396        }
13397
13398        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13399            AppErrorResult result = new AppErrorResult();
13400            synchronized (this) {
13401                final long origId = Binder.clearCallingIdentity();
13402
13403                Message msg = Message.obtain();
13404                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13405                HashMap<String, Object> data = new HashMap<String, Object>();
13406                data.put("result", result);
13407                data.put("app", r);
13408                data.put("violationMask", violationMask);
13409                data.put("info", info);
13410                msg.obj = data;
13411                mUiHandler.sendMessage(msg);
13412
13413                Binder.restoreCallingIdentity(origId);
13414            }
13415            int res = result.get();
13416            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13417        }
13418    }
13419
13420    // Depending on the policy in effect, there could be a bunch of
13421    // these in quick succession so we try to batch these together to
13422    // minimize disk writes, number of dropbox entries, and maximize
13423    // compression, by having more fewer, larger records.
13424    private void logStrictModeViolationToDropBox(
13425            ProcessRecord process,
13426            StrictMode.ViolationInfo info) {
13427        if (info == null) {
13428            return;
13429        }
13430        final boolean isSystemApp = process == null ||
13431                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13432                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13433        final String processName = process == null ? "unknown" : process.processName;
13434        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13435        final DropBoxManager dbox = (DropBoxManager)
13436                mContext.getSystemService(Context.DROPBOX_SERVICE);
13437
13438        // Exit early if the dropbox isn't configured to accept this report type.
13439        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13440
13441        boolean bufferWasEmpty;
13442        boolean needsFlush;
13443        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13444        synchronized (sb) {
13445            bufferWasEmpty = sb.length() == 0;
13446            appendDropBoxProcessHeaders(process, processName, sb);
13447            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13448            sb.append("System-App: ").append(isSystemApp).append("\n");
13449            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13450            if (info.violationNumThisLoop != 0) {
13451                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13452            }
13453            if (info.numAnimationsRunning != 0) {
13454                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13455            }
13456            if (info.broadcastIntentAction != null) {
13457                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13458            }
13459            if (info.durationMillis != -1) {
13460                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13461            }
13462            if (info.numInstances != -1) {
13463                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13464            }
13465            if (info.tags != null) {
13466                for (String tag : info.tags) {
13467                    sb.append("Span-Tag: ").append(tag).append("\n");
13468                }
13469            }
13470            sb.append("\n");
13471            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13472                sb.append(info.crashInfo.stackTrace);
13473                sb.append("\n");
13474            }
13475            if (info.message != null) {
13476                sb.append(info.message);
13477                sb.append("\n");
13478            }
13479
13480            // Only buffer up to ~64k.  Various logging bits truncate
13481            // things at 128k.
13482            needsFlush = (sb.length() > 64 * 1024);
13483        }
13484
13485        // Flush immediately if the buffer's grown too large, or this
13486        // is a non-system app.  Non-system apps are isolated with a
13487        // different tag & policy and not batched.
13488        //
13489        // Batching is useful during internal testing with
13490        // StrictMode settings turned up high.  Without batching,
13491        // thousands of separate files could be created on boot.
13492        if (!isSystemApp || needsFlush) {
13493            new Thread("Error dump: " + dropboxTag) {
13494                @Override
13495                public void run() {
13496                    String report;
13497                    synchronized (sb) {
13498                        report = sb.toString();
13499                        sb.delete(0, sb.length());
13500                        sb.trimToSize();
13501                    }
13502                    if (report.length() != 0) {
13503                        dbox.addText(dropboxTag, report);
13504                    }
13505                }
13506            }.start();
13507            return;
13508        }
13509
13510        // System app batching:
13511        if (!bufferWasEmpty) {
13512            // An existing dropbox-writing thread is outstanding, so
13513            // we don't need to start it up.  The existing thread will
13514            // catch the buffer appends we just did.
13515            return;
13516        }
13517
13518        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13519        // (After this point, we shouldn't access AMS internal data structures.)
13520        new Thread("Error dump: " + dropboxTag) {
13521            @Override
13522            public void run() {
13523                // 5 second sleep to let stacks arrive and be batched together
13524                try {
13525                    Thread.sleep(5000);  // 5 seconds
13526                } catch (InterruptedException e) {}
13527
13528                String errorReport;
13529                synchronized (mStrictModeBuffer) {
13530                    errorReport = mStrictModeBuffer.toString();
13531                    if (errorReport.length() == 0) {
13532                        return;
13533                    }
13534                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13535                    mStrictModeBuffer.trimToSize();
13536                }
13537                dbox.addText(dropboxTag, errorReport);
13538            }
13539        }.start();
13540    }
13541
13542    /**
13543     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13544     * @param app object of the crashing app, null for the system server
13545     * @param tag reported by the caller
13546     * @param system whether this wtf is coming from the system
13547     * @param crashInfo describing the context of the error
13548     * @return true if the process should exit immediately (WTF is fatal)
13549     */
13550    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13551            final ApplicationErrorReport.CrashInfo crashInfo) {
13552        final int callingUid = Binder.getCallingUid();
13553        final int callingPid = Binder.getCallingPid();
13554
13555        if (system) {
13556            // If this is coming from the system, we could very well have low-level
13557            // system locks held, so we want to do this all asynchronously.  And we
13558            // never want this to become fatal, so there is that too.
13559            mHandler.post(new Runnable() {
13560                @Override public void run() {
13561                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13562                }
13563            });
13564            return false;
13565        }
13566
13567        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13568                crashInfo);
13569
13570        if (r != null && r.pid != Process.myPid() &&
13571                Settings.Global.getInt(mContext.getContentResolver(),
13572                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13573            mAppErrors.crashApplication(r, crashInfo);
13574            return true;
13575        } else {
13576            return false;
13577        }
13578    }
13579
13580    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13581            final ApplicationErrorReport.CrashInfo crashInfo) {
13582        final ProcessRecord r = findAppProcess(app, "WTF");
13583        final String processName = app == null ? "system_server"
13584                : (r == null ? "unknown" : r.processName);
13585
13586        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13587                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13588
13589        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13590
13591        return r;
13592    }
13593
13594    /**
13595     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13596     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13597     */
13598    private ProcessRecord findAppProcess(IBinder app, String reason) {
13599        if (app == null) {
13600            return null;
13601        }
13602
13603        synchronized (this) {
13604            final int NP = mProcessNames.getMap().size();
13605            for (int ip=0; ip<NP; ip++) {
13606                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13607                final int NA = apps.size();
13608                for (int ia=0; ia<NA; ia++) {
13609                    ProcessRecord p = apps.valueAt(ia);
13610                    if (p.thread != null && p.thread.asBinder() == app) {
13611                        return p;
13612                    }
13613                }
13614            }
13615
13616            Slog.w(TAG, "Can't find mystery application for " + reason
13617                    + " from pid=" + Binder.getCallingPid()
13618                    + " uid=" + Binder.getCallingUid() + ": " + app);
13619            return null;
13620        }
13621    }
13622
13623    /**
13624     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13625     * to append various headers to the dropbox log text.
13626     */
13627    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13628            StringBuilder sb) {
13629        // Watchdog thread ends up invoking this function (with
13630        // a null ProcessRecord) to add the stack file to dropbox.
13631        // Do not acquire a lock on this (am) in such cases, as it
13632        // could cause a potential deadlock, if and when watchdog
13633        // is invoked due to unavailability of lock on am and it
13634        // would prevent watchdog from killing system_server.
13635        if (process == null) {
13636            sb.append("Process: ").append(processName).append("\n");
13637            return;
13638        }
13639        // Note: ProcessRecord 'process' is guarded by the service
13640        // instance.  (notably process.pkgList, which could otherwise change
13641        // concurrently during execution of this method)
13642        synchronized (this) {
13643            sb.append("Process: ").append(processName).append("\n");
13644            int flags = process.info.flags;
13645            IPackageManager pm = AppGlobals.getPackageManager();
13646            sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
13647            for (int ip=0; ip<process.pkgList.size(); ip++) {
13648                String pkg = process.pkgList.keyAt(ip);
13649                sb.append("Package: ").append(pkg);
13650                try {
13651                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13652                    if (pi != null) {
13653                        sb.append(" v").append(pi.versionCode);
13654                        if (pi.versionName != null) {
13655                            sb.append(" (").append(pi.versionName).append(")");
13656                        }
13657                    }
13658                } catch (RemoteException e) {
13659                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13660                }
13661                sb.append("\n");
13662            }
13663        }
13664    }
13665
13666    private static String processClass(ProcessRecord process) {
13667        if (process == null || process.pid == MY_PID) {
13668            return "system_server";
13669        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13670            return "system_app";
13671        } else {
13672            return "data_app";
13673        }
13674    }
13675
13676    private volatile long mWtfClusterStart;
13677    private volatile int mWtfClusterCount;
13678
13679    /**
13680     * Write a description of an error (crash, WTF, ANR) to the drop box.
13681     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13682     * @param process which caused the error, null means the system server
13683     * @param activity which triggered the error, null if unknown
13684     * @param parent activity related to the error, null if unknown
13685     * @param subject line related to the error, null if absent
13686     * @param report in long form describing the error, null if absent
13687     * @param dataFile text file to include in the report, null if none
13688     * @param crashInfo giving an application stack trace, null if absent
13689     */
13690    public void addErrorToDropBox(String eventType,
13691            ProcessRecord process, String processName, ActivityRecord activity,
13692            ActivityRecord parent, String subject,
13693            final String report, final File dataFile,
13694            final ApplicationErrorReport.CrashInfo crashInfo) {
13695        // NOTE -- this must never acquire the ActivityManagerService lock,
13696        // otherwise the watchdog may be prevented from resetting the system.
13697
13698        // Bail early if not published yet
13699        if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
13700        final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
13701
13702        // Exit early if the dropbox isn't configured to accept this report type.
13703        final String dropboxTag = processClass(process) + "_" + eventType;
13704        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13705
13706        // Rate-limit how often we're willing to do the heavy lifting below to
13707        // collect and record logs; currently 5 logs per 10 second period.
13708        final long now = SystemClock.elapsedRealtime();
13709        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13710            mWtfClusterStart = now;
13711            mWtfClusterCount = 1;
13712        } else {
13713            if (mWtfClusterCount++ >= 5) return;
13714        }
13715
13716        final StringBuilder sb = new StringBuilder(1024);
13717        appendDropBoxProcessHeaders(process, processName, sb);
13718        if (process != null) {
13719            sb.append("Foreground: ")
13720                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13721                    .append("\n");
13722        }
13723        if (activity != null) {
13724            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13725        }
13726        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13727            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13728        }
13729        if (parent != null && parent != activity) {
13730            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13731        }
13732        if (subject != null) {
13733            sb.append("Subject: ").append(subject).append("\n");
13734        }
13735        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13736        if (Debug.isDebuggerConnected()) {
13737            sb.append("Debugger: Connected\n");
13738        }
13739        sb.append("\n");
13740
13741        // Do the rest in a worker thread to avoid blocking the caller on I/O
13742        // (After this point, we shouldn't access AMS internal data structures.)
13743        Thread worker = new Thread("Error dump: " + dropboxTag) {
13744            @Override
13745            public void run() {
13746                if (report != null) {
13747                    sb.append(report);
13748                }
13749
13750                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13751                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13752                int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
13753                        - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
13754
13755                if (dataFile != null && maxDataFileSize > 0) {
13756                    try {
13757                        sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
13758                                    "\n\n[[TRUNCATED]]"));
13759                    } catch (IOException e) {
13760                        Slog.e(TAG, "Error reading " + dataFile, e);
13761                    }
13762                }
13763                if (crashInfo != null && crashInfo.stackTrace != null) {
13764                    sb.append(crashInfo.stackTrace);
13765                }
13766
13767                if (lines > 0) {
13768                    sb.append("\n");
13769
13770                    // Merge several logcat streams, and take the last N lines
13771                    InputStreamReader input = null;
13772                    try {
13773                        java.lang.Process logcat = new ProcessBuilder(
13774                                "/system/bin/timeout", "-k", "15s", "10s",
13775                                "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
13776                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13777                                        .redirectErrorStream(true).start();
13778
13779                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13780                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13781                        input = new InputStreamReader(logcat.getInputStream());
13782
13783                        int num;
13784                        char[] buf = new char[8192];
13785                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13786                    } catch (IOException e) {
13787                        Slog.e(TAG, "Error running logcat", e);
13788                    } finally {
13789                        if (input != null) try { input.close(); } catch (IOException e) {}
13790                    }
13791                }
13792
13793                dbox.addText(dropboxTag, sb.toString());
13794            }
13795        };
13796
13797        if (process == null) {
13798            // If process is null, we are being called from some internal code
13799            // and may be about to die -- run this synchronously.
13800            worker.run();
13801        } else {
13802            worker.start();
13803        }
13804    }
13805
13806    @Override
13807    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13808        enforceNotIsolatedCaller("getProcessesInErrorState");
13809        // assume our apps are happy - lazy create the list
13810        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13811
13812        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13813                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13814        int userId = UserHandle.getUserId(Binder.getCallingUid());
13815
13816        synchronized (this) {
13817
13818            // iterate across all processes
13819            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13820                ProcessRecord app = mLruProcesses.get(i);
13821                if (!allUsers && app.userId != userId) {
13822                    continue;
13823                }
13824                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13825                    // This one's in trouble, so we'll generate a report for it
13826                    // crashes are higher priority (in case there's a crash *and* an anr)
13827                    ActivityManager.ProcessErrorStateInfo report = null;
13828                    if (app.crashing) {
13829                        report = app.crashingReport;
13830                    } else if (app.notResponding) {
13831                        report = app.notRespondingReport;
13832                    }
13833
13834                    if (report != null) {
13835                        if (errList == null) {
13836                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13837                        }
13838                        errList.add(report);
13839                    } else {
13840                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13841                                " crashing = " + app.crashing +
13842                                " notResponding = " + app.notResponding);
13843                    }
13844                }
13845            }
13846        }
13847
13848        return errList;
13849    }
13850
13851    static int procStateToImportance(int procState, int memAdj,
13852            ActivityManager.RunningAppProcessInfo currApp) {
13853        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13854        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13855            currApp.lru = memAdj;
13856        } else {
13857            currApp.lru = 0;
13858        }
13859        return imp;
13860    }
13861
13862    private void fillInProcMemInfo(ProcessRecord app,
13863            ActivityManager.RunningAppProcessInfo outInfo) {
13864        outInfo.pid = app.pid;
13865        outInfo.uid = app.info.uid;
13866        if (mHeavyWeightProcess == app) {
13867            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13868        }
13869        if (app.persistent) {
13870            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13871        }
13872        if (app.activities.size() > 0) {
13873            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13874        }
13875        outInfo.lastTrimLevel = app.trimMemoryLevel;
13876        int adj = app.curAdj;
13877        int procState = app.curProcState;
13878        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13879        outInfo.importanceReasonCode = app.adjTypeCode;
13880        outInfo.processState = app.curProcState;
13881    }
13882
13883    @Override
13884    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13885        enforceNotIsolatedCaller("getRunningAppProcesses");
13886
13887        final int callingUid = Binder.getCallingUid();
13888
13889        // Lazy instantiation of list
13890        List<ActivityManager.RunningAppProcessInfo> runList = null;
13891        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13892                callingUid) == PackageManager.PERMISSION_GRANTED;
13893        final int userId = UserHandle.getUserId(callingUid);
13894        final boolean allUids = isGetTasksAllowed(
13895                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13896
13897        synchronized (this) {
13898            // Iterate across all processes
13899            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13900                ProcessRecord app = mLruProcesses.get(i);
13901                if ((!allUsers && app.userId != userId)
13902                        || (!allUids && app.uid != callingUid)) {
13903                    continue;
13904                }
13905                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13906                    // Generate process state info for running application
13907                    ActivityManager.RunningAppProcessInfo currApp =
13908                        new ActivityManager.RunningAppProcessInfo(app.processName,
13909                                app.pid, app.getPackageList());
13910                    fillInProcMemInfo(app, currApp);
13911                    if (app.adjSource instanceof ProcessRecord) {
13912                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13913                        currApp.importanceReasonImportance =
13914                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13915                                        app.adjSourceProcState);
13916                    } else if (app.adjSource instanceof ActivityRecord) {
13917                        ActivityRecord r = (ActivityRecord)app.adjSource;
13918                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13919                    }
13920                    if (app.adjTarget instanceof ComponentName) {
13921                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13922                    }
13923                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13924                    //        + " lru=" + currApp.lru);
13925                    if (runList == null) {
13926                        runList = new ArrayList<>();
13927                    }
13928                    runList.add(currApp);
13929                }
13930            }
13931        }
13932        return runList;
13933    }
13934
13935    @Override
13936    public List<ApplicationInfo> getRunningExternalApplications() {
13937        enforceNotIsolatedCaller("getRunningExternalApplications");
13938        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13939        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13940        if (runningApps != null && runningApps.size() > 0) {
13941            Set<String> extList = new HashSet<String>();
13942            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13943                if (app.pkgList != null) {
13944                    for (String pkg : app.pkgList) {
13945                        extList.add(pkg);
13946                    }
13947                }
13948            }
13949            IPackageManager pm = AppGlobals.getPackageManager();
13950            for (String pkg : extList) {
13951                try {
13952                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13953                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13954                        retList.add(info);
13955                    }
13956                } catch (RemoteException e) {
13957                }
13958            }
13959        }
13960        return retList;
13961    }
13962
13963    @Override
13964    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13965        enforceNotIsolatedCaller("getMyMemoryState");
13966        synchronized (this) {
13967            ProcessRecord proc;
13968            synchronized (mPidsSelfLocked) {
13969                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13970            }
13971            fillInProcMemInfo(proc, outInfo);
13972        }
13973    }
13974
13975    @Override
13976    public int getMemoryTrimLevel() {
13977        enforceNotIsolatedCaller("getMyMemoryState");
13978        synchronized (this) {
13979            return mLastMemoryLevel;
13980        }
13981    }
13982
13983    @Override
13984    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13985            FileDescriptor err, String[] args, ShellCallback callback,
13986            ResultReceiver resultReceiver) {
13987        (new ActivityManagerShellCommand(this, false)).exec(
13988                this, in, out, err, args, callback, resultReceiver);
13989    }
13990
13991    @Override
13992    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13993        if (checkCallingPermission(android.Manifest.permission.DUMP)
13994                != PackageManager.PERMISSION_GRANTED) {
13995            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13996                    + Binder.getCallingPid()
13997                    + ", uid=" + Binder.getCallingUid()
13998                    + " without permission "
13999                    + android.Manifest.permission.DUMP);
14000            return;
14001        }
14002
14003        boolean dumpAll = false;
14004        boolean dumpClient = false;
14005        boolean dumpCheckin = false;
14006        boolean dumpCheckinFormat = false;
14007        boolean dumpVisibleStacks = false;
14008        String dumpPackage = null;
14009
14010        int opti = 0;
14011        while (opti < args.length) {
14012            String opt = args[opti];
14013            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14014                break;
14015            }
14016            opti++;
14017            if ("-a".equals(opt)) {
14018                dumpAll = true;
14019            } else if ("-c".equals(opt)) {
14020                dumpClient = true;
14021            } else if ("-v".equals(opt)) {
14022                dumpVisibleStacks = true;
14023            } else if ("-p".equals(opt)) {
14024                if (opti < args.length) {
14025                    dumpPackage = args[opti];
14026                    opti++;
14027                } else {
14028                    pw.println("Error: -p option requires package argument");
14029                    return;
14030                }
14031                dumpClient = true;
14032            } else if ("--checkin".equals(opt)) {
14033                dumpCheckin = dumpCheckinFormat = true;
14034            } else if ("-C".equals(opt)) {
14035                dumpCheckinFormat = true;
14036            } else if ("-h".equals(opt)) {
14037                ActivityManagerShellCommand.dumpHelp(pw, true);
14038                return;
14039            } else {
14040                pw.println("Unknown argument: " + opt + "; use -h for help");
14041            }
14042        }
14043
14044        long origId = Binder.clearCallingIdentity();
14045        boolean more = false;
14046        // Is the caller requesting to dump a particular piece of data?
14047        if (opti < args.length) {
14048            String cmd = args[opti];
14049            opti++;
14050            if ("activities".equals(cmd) || "a".equals(cmd)) {
14051                synchronized (this) {
14052                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14053                }
14054            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
14055                synchronized (this) {
14056                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
14057                }
14058            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
14059                String[] newArgs;
14060                String name;
14061                if (opti >= args.length) {
14062                    name = null;
14063                    newArgs = EMPTY_STRING_ARRAY;
14064                } else {
14065                    dumpPackage = args[opti];
14066                    opti++;
14067                    newArgs = new String[args.length - opti];
14068                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14069                            args.length - opti);
14070                }
14071                synchronized (this) {
14072                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
14073                }
14074            } else if ("broadcast-stats".equals(cmd)) {
14075                String[] newArgs;
14076                String name;
14077                if (opti >= args.length) {
14078                    name = null;
14079                    newArgs = EMPTY_STRING_ARRAY;
14080                } else {
14081                    dumpPackage = args[opti];
14082                    opti++;
14083                    newArgs = new String[args.length - opti];
14084                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14085                            args.length - opti);
14086                }
14087                synchronized (this) {
14088                    if (dumpCheckinFormat) {
14089                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
14090                                dumpPackage);
14091                    } else {
14092                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
14093                    }
14094                }
14095            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
14096                String[] newArgs;
14097                String name;
14098                if (opti >= args.length) {
14099                    name = null;
14100                    newArgs = EMPTY_STRING_ARRAY;
14101                } else {
14102                    dumpPackage = args[opti];
14103                    opti++;
14104                    newArgs = new String[args.length - opti];
14105                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14106                            args.length - opti);
14107                }
14108                synchronized (this) {
14109                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
14110                }
14111            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
14112                String[] newArgs;
14113                String name;
14114                if (opti >= args.length) {
14115                    name = null;
14116                    newArgs = EMPTY_STRING_ARRAY;
14117                } else {
14118                    dumpPackage = args[opti];
14119                    opti++;
14120                    newArgs = new String[args.length - opti];
14121                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14122                            args.length - opti);
14123                }
14124                synchronized (this) {
14125                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
14126                }
14127            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
14128                synchronized (this) {
14129                    dumpOomLocked(fd, pw, args, opti, true);
14130                }
14131            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
14132                synchronized (this) {
14133                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
14134                }
14135            } else if ("provider".equals(cmd)) {
14136                String[] newArgs;
14137                String name;
14138                if (opti >= args.length) {
14139                    name = null;
14140                    newArgs = EMPTY_STRING_ARRAY;
14141                } else {
14142                    name = args[opti];
14143                    opti++;
14144                    newArgs = new String[args.length - opti];
14145                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14146                }
14147                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
14148                    pw.println("No providers match: " + name);
14149                    pw.println("Use -h for help.");
14150                }
14151            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
14152                synchronized (this) {
14153                    dumpProvidersLocked(fd, pw, args, opti, true, null);
14154                }
14155            } else if ("service".equals(cmd)) {
14156                String[] newArgs;
14157                String name;
14158                if (opti >= args.length) {
14159                    name = null;
14160                    newArgs = EMPTY_STRING_ARRAY;
14161                } else {
14162                    name = args[opti];
14163                    opti++;
14164                    newArgs = new String[args.length - opti];
14165                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14166                            args.length - opti);
14167                }
14168                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14169                    pw.println("No services match: " + name);
14170                    pw.println("Use -h for help.");
14171                }
14172            } else if ("package".equals(cmd)) {
14173                String[] newArgs;
14174                if (opti >= args.length) {
14175                    pw.println("package: no package name specified");
14176                    pw.println("Use -h for help.");
14177                } else {
14178                    dumpPackage = args[opti];
14179                    opti++;
14180                    newArgs = new String[args.length - opti];
14181                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14182                            args.length - opti);
14183                    args = newArgs;
14184                    opti = 0;
14185                    more = true;
14186                }
14187            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14188                synchronized (this) {
14189                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14190                }
14191            } else if ("services".equals(cmd) || "s".equals(cmd)) {
14192                if (dumpClient) {
14193                    ActiveServices.ServiceDumper dumper;
14194                    synchronized (this) {
14195                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14196                                dumpPackage);
14197                    }
14198                    dumper.dumpWithClient();
14199                } else {
14200                    synchronized (this) {
14201                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14202                                dumpPackage).dumpLocked();
14203                    }
14204                }
14205            } else if ("locks".equals(cmd)) {
14206                LockGuard.dump(fd, pw, args);
14207            } else if ("pip".equals(cmd)) {
14208                Rect bounds = getDefaultPictureInPictureBounds(DEFAULT_DISPLAY);
14209                pw.print("defaultBounds="); bounds.printShortString(pw);
14210                pw.println();
14211                bounds = getPictureInPictureMovementBounds(DEFAULT_DISPLAY);
14212                pw.print("movementBounds="); bounds.printShortString(pw);
14213                pw.println();
14214            } else {
14215                // Dumping a single activity?
14216                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacks)) {
14217                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14218                    int res = shell.exec(this, null, fd, null, args, null,
14219                            new ResultReceiver(null));
14220                    if (res < 0) {
14221                        pw.println("Bad activity command, or no activities match: " + cmd);
14222                        pw.println("Use -h for help.");
14223                    }
14224                }
14225            }
14226            if (!more) {
14227                Binder.restoreCallingIdentity(origId);
14228                return;
14229            }
14230        }
14231
14232        // No piece of data specified, dump everything.
14233        if (dumpCheckinFormat) {
14234            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14235        } else if (dumpClient) {
14236            ActiveServices.ServiceDumper sdumper;
14237            synchronized (this) {
14238                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14239                pw.println();
14240                if (dumpAll) {
14241                    pw.println("-------------------------------------------------------------------------------");
14242                }
14243                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14244                pw.println();
14245                if (dumpAll) {
14246                    pw.println("-------------------------------------------------------------------------------");
14247                }
14248                if (dumpAll || dumpPackage != null) {
14249                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14250                    pw.println();
14251                    if (dumpAll) {
14252                        pw.println("-------------------------------------------------------------------------------");
14253                    }
14254                }
14255                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14256                pw.println();
14257                if (dumpAll) {
14258                    pw.println("-------------------------------------------------------------------------------");
14259                }
14260                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14261                pw.println();
14262                if (dumpAll) {
14263                    pw.println("-------------------------------------------------------------------------------");
14264                }
14265                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14266                        dumpPackage);
14267            }
14268            sdumper.dumpWithClient();
14269            pw.println();
14270            synchronized (this) {
14271                if (dumpAll) {
14272                    pw.println("-------------------------------------------------------------------------------");
14273                }
14274                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14275                pw.println();
14276                if (dumpAll) {
14277                    pw.println("-------------------------------------------------------------------------------");
14278                }
14279                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14280                if (mAssociations.size() > 0) {
14281                    pw.println();
14282                    if (dumpAll) {
14283                        pw.println("-------------------------------------------------------------------------------");
14284                    }
14285                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14286                }
14287                pw.println();
14288                if (dumpAll) {
14289                    pw.println("-------------------------------------------------------------------------------");
14290                }
14291                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14292            }
14293
14294        } else {
14295            synchronized (this) {
14296                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14297                pw.println();
14298                if (dumpAll) {
14299                    pw.println("-------------------------------------------------------------------------------");
14300                }
14301                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14302                pw.println();
14303                if (dumpAll) {
14304                    pw.println("-------------------------------------------------------------------------------");
14305                }
14306                if (dumpAll || dumpPackage != null) {
14307                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14308                    pw.println();
14309                    if (dumpAll) {
14310                        pw.println("-------------------------------------------------------------------------------");
14311                    }
14312                }
14313                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14314                pw.println();
14315                if (dumpAll) {
14316                    pw.println("-------------------------------------------------------------------------------");
14317                }
14318                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14319                pw.println();
14320                if (dumpAll) {
14321                    pw.println("-------------------------------------------------------------------------------");
14322                }
14323                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14324                        .dumpLocked();
14325                pw.println();
14326                if (dumpAll) {
14327                    pw.println("-------------------------------------------------------------------------------");
14328                }
14329                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14330                pw.println();
14331                if (dumpAll) {
14332                    pw.println("-------------------------------------------------------------------------------");
14333                }
14334                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14335                if (mAssociations.size() > 0) {
14336                    pw.println();
14337                    if (dumpAll) {
14338                        pw.println("-------------------------------------------------------------------------------");
14339                    }
14340                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14341                }
14342                pw.println();
14343                if (dumpAll) {
14344                    pw.println("-------------------------------------------------------------------------------");
14345                }
14346                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14347            }
14348        }
14349        Binder.restoreCallingIdentity(origId);
14350    }
14351
14352    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14353            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14354        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14355
14356        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14357                dumpPackage);
14358        boolean needSep = printedAnything;
14359
14360        boolean printed = ActivityStackSupervisor.printThisActivity(pw,
14361                mStackSupervisor.getResumedActivityLocked(),
14362                dumpPackage, needSep, "  ResumedActivity: ");
14363        if (printed) {
14364            printedAnything = true;
14365            needSep = false;
14366        }
14367
14368        if (dumpPackage == null) {
14369            if (needSep) {
14370                pw.println();
14371            }
14372            needSep = true;
14373            printedAnything = true;
14374            mStackSupervisor.dump(pw, "  ");
14375        }
14376
14377        if (!printedAnything) {
14378            pw.println("  (nothing)");
14379        }
14380    }
14381
14382    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14383            int opti, boolean dumpAll, String dumpPackage) {
14384        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14385
14386        boolean printedAnything = false;
14387
14388        if (mRecentTasks != null && mRecentTasks.size() > 0) {
14389            boolean printedHeader = false;
14390
14391            final int N = mRecentTasks.size();
14392            for (int i=0; i<N; i++) {
14393                TaskRecord tr = mRecentTasks.get(i);
14394                if (dumpPackage != null) {
14395                    if (tr.realActivity == null ||
14396                            !dumpPackage.equals(tr.realActivity.getPackageName())) {
14397                        continue;
14398                    }
14399                }
14400                if (!printedHeader) {
14401                    pw.println("  Recent tasks:");
14402                    printedHeader = true;
14403                    printedAnything = true;
14404                }
14405                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14406                        pw.println(tr);
14407                if (dumpAll) {
14408                    mRecentTasks.get(i).dump(pw, "    ");
14409                }
14410            }
14411        }
14412
14413        if (!printedAnything) {
14414            pw.println("  (nothing)");
14415        }
14416    }
14417
14418    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14419            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14420        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14421
14422        int dumpUid = 0;
14423        if (dumpPackage != null) {
14424            IPackageManager pm = AppGlobals.getPackageManager();
14425            try {
14426                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14427            } catch (RemoteException e) {
14428            }
14429        }
14430
14431        boolean printedAnything = false;
14432
14433        final long now = SystemClock.uptimeMillis();
14434
14435        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14436            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14437                    = mAssociations.valueAt(i1);
14438            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14439                SparseArray<ArrayMap<String, Association>> sourceUids
14440                        = targetComponents.valueAt(i2);
14441                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14442                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14443                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14444                        Association ass = sourceProcesses.valueAt(i4);
14445                        if (dumpPackage != null) {
14446                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14447                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14448                                continue;
14449                            }
14450                        }
14451                        printedAnything = true;
14452                        pw.print("  ");
14453                        pw.print(ass.mTargetProcess);
14454                        pw.print("/");
14455                        UserHandle.formatUid(pw, ass.mTargetUid);
14456                        pw.print(" <- ");
14457                        pw.print(ass.mSourceProcess);
14458                        pw.print("/");
14459                        UserHandle.formatUid(pw, ass.mSourceUid);
14460                        pw.println();
14461                        pw.print("    via ");
14462                        pw.print(ass.mTargetComponent.flattenToShortString());
14463                        pw.println();
14464                        pw.print("    ");
14465                        long dur = ass.mTime;
14466                        if (ass.mNesting > 0) {
14467                            dur += now - ass.mStartTime;
14468                        }
14469                        TimeUtils.formatDuration(dur, pw);
14470                        pw.print(" (");
14471                        pw.print(ass.mCount);
14472                        pw.print(" times)");
14473                        pw.print("  ");
14474                        for (int i=0; i<ass.mStateTimes.length; i++) {
14475                            long amt = ass.mStateTimes[i];
14476                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14477                                amt += now - ass.mLastStateUptime;
14478                            }
14479                            if (amt != 0) {
14480                                pw.print(" ");
14481                                pw.print(ProcessList.makeProcStateString(
14482                                            i + ActivityManager.MIN_PROCESS_STATE));
14483                                pw.print("=");
14484                                TimeUtils.formatDuration(amt, pw);
14485                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14486                                    pw.print("*");
14487                                }
14488                            }
14489                        }
14490                        pw.println();
14491                        if (ass.mNesting > 0) {
14492                            pw.print("    Currently active: ");
14493                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14494                            pw.println();
14495                        }
14496                    }
14497                }
14498            }
14499
14500        }
14501
14502        if (!printedAnything) {
14503            pw.println("  (nothing)");
14504        }
14505    }
14506
14507    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14508            String header, boolean needSep) {
14509        boolean printed = false;
14510        int whichAppId = -1;
14511        if (dumpPackage != null) {
14512            try {
14513                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14514                        dumpPackage, 0);
14515                whichAppId = UserHandle.getAppId(info.uid);
14516            } catch (NameNotFoundException e) {
14517                e.printStackTrace();
14518            }
14519        }
14520        for (int i=0; i<uids.size(); i++) {
14521            UidRecord uidRec = uids.valueAt(i);
14522            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14523                continue;
14524            }
14525            if (!printed) {
14526                printed = true;
14527                if (needSep) {
14528                    pw.println();
14529                }
14530                pw.print("  ");
14531                pw.println(header);
14532                needSep = true;
14533            }
14534            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14535            pw.print(": "); pw.println(uidRec);
14536        }
14537        return printed;
14538    }
14539
14540    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14541            int opti, boolean dumpAll, String dumpPackage) {
14542        boolean needSep = false;
14543        boolean printedAnything = false;
14544        int numPers = 0;
14545
14546        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14547
14548        if (dumpAll) {
14549            final int NP = mProcessNames.getMap().size();
14550            for (int ip=0; ip<NP; ip++) {
14551                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14552                final int NA = procs.size();
14553                for (int ia=0; ia<NA; ia++) {
14554                    ProcessRecord r = procs.valueAt(ia);
14555                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14556                        continue;
14557                    }
14558                    if (!needSep) {
14559                        pw.println("  All known processes:");
14560                        needSep = true;
14561                        printedAnything = true;
14562                    }
14563                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14564                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14565                        pw.print(" "); pw.println(r);
14566                    r.dump(pw, "    ");
14567                    if (r.persistent) {
14568                        numPers++;
14569                    }
14570                }
14571            }
14572        }
14573
14574        if (mIsolatedProcesses.size() > 0) {
14575            boolean printed = false;
14576            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14577                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14578                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14579                    continue;
14580                }
14581                if (!printed) {
14582                    if (needSep) {
14583                        pw.println();
14584                    }
14585                    pw.println("  Isolated process list (sorted by uid):");
14586                    printedAnything = true;
14587                    printed = true;
14588                    needSep = true;
14589                }
14590                pw.println(String.format("%sIsolated #%2d: %s",
14591                        "    ", i, r.toString()));
14592            }
14593        }
14594
14595        if (mActiveUids.size() > 0) {
14596            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14597                printedAnything = needSep = true;
14598            }
14599        }
14600        if (mValidateUids.size() > 0) {
14601            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14602                printedAnything = needSep = true;
14603            }
14604        }
14605
14606        if (mLruProcesses.size() > 0) {
14607            if (needSep) {
14608                pw.println();
14609            }
14610            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14611                    pw.print(" total, non-act at ");
14612                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14613                    pw.print(", non-svc at ");
14614                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14615                    pw.println("):");
14616            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14617            needSep = true;
14618            printedAnything = true;
14619        }
14620
14621        if (dumpAll || dumpPackage != null) {
14622            synchronized (mPidsSelfLocked) {
14623                boolean printed = false;
14624                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14625                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14626                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14627                        continue;
14628                    }
14629                    if (!printed) {
14630                        if (needSep) pw.println();
14631                        needSep = true;
14632                        pw.println("  PID mappings:");
14633                        printed = true;
14634                        printedAnything = true;
14635                    }
14636                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14637                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14638                }
14639            }
14640        }
14641
14642        if (mForegroundProcesses.size() > 0) {
14643            synchronized (mPidsSelfLocked) {
14644                boolean printed = false;
14645                for (int i=0; i<mForegroundProcesses.size(); i++) {
14646                    ProcessRecord r = mPidsSelfLocked.get(
14647                            mForegroundProcesses.valueAt(i).pid);
14648                    if (dumpPackage != null && (r == null
14649                            || !r.pkgList.containsKey(dumpPackage))) {
14650                        continue;
14651                    }
14652                    if (!printed) {
14653                        if (needSep) pw.println();
14654                        needSep = true;
14655                        pw.println("  Foreground Processes:");
14656                        printed = true;
14657                        printedAnything = true;
14658                    }
14659                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14660                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14661                }
14662            }
14663        }
14664
14665        if (mPersistentStartingProcesses.size() > 0) {
14666            if (needSep) pw.println();
14667            needSep = true;
14668            printedAnything = true;
14669            pw.println("  Persisent processes that are starting:");
14670            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14671                    "Starting Norm", "Restarting PERS", dumpPackage);
14672        }
14673
14674        if (mRemovedProcesses.size() > 0) {
14675            if (needSep) pw.println();
14676            needSep = true;
14677            printedAnything = true;
14678            pw.println("  Processes that are being removed:");
14679            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14680                    "Removed Norm", "Removed PERS", dumpPackage);
14681        }
14682
14683        if (mProcessesOnHold.size() > 0) {
14684            if (needSep) pw.println();
14685            needSep = true;
14686            printedAnything = true;
14687            pw.println("  Processes that are on old until the system is ready:");
14688            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14689                    "OnHold Norm", "OnHold PERS", dumpPackage);
14690        }
14691
14692        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14693
14694        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14695        if (needSep) {
14696            printedAnything = true;
14697        }
14698
14699        if (dumpPackage == null) {
14700            pw.println();
14701            needSep = false;
14702            mUserController.dump(pw, dumpAll);
14703        }
14704        if (mHomeProcess != null && (dumpPackage == null
14705                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14706            if (needSep) {
14707                pw.println();
14708                needSep = false;
14709            }
14710            pw.println("  mHomeProcess: " + mHomeProcess);
14711        }
14712        if (mPreviousProcess != null && (dumpPackage == null
14713                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14714            if (needSep) {
14715                pw.println();
14716                needSep = false;
14717            }
14718            pw.println("  mPreviousProcess: " + mPreviousProcess);
14719        }
14720        if (dumpAll) {
14721            StringBuilder sb = new StringBuilder(128);
14722            sb.append("  mPreviousProcessVisibleTime: ");
14723            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14724            pw.println(sb);
14725        }
14726        if (mHeavyWeightProcess != null && (dumpPackage == null
14727                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14728            if (needSep) {
14729                pw.println();
14730                needSep = false;
14731            }
14732            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14733        }
14734        if (dumpPackage == null) {
14735            pw.println("  mGlobalConfiguration: " + getGlobalConfiguration());
14736            mStackSupervisor.dumpDisplayConfigs(pw, "  ");
14737        }
14738        if (dumpAll) {
14739            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14740            if (mCompatModePackages.getPackages().size() > 0) {
14741                boolean printed = false;
14742                for (Map.Entry<String, Integer> entry
14743                        : mCompatModePackages.getPackages().entrySet()) {
14744                    String pkg = entry.getKey();
14745                    int mode = entry.getValue();
14746                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14747                        continue;
14748                    }
14749                    if (!printed) {
14750                        pw.println("  mScreenCompatPackages:");
14751                        printed = true;
14752                    }
14753                    pw.print("    "); pw.print(pkg); pw.print(": ");
14754                            pw.print(mode); pw.println();
14755                }
14756            }
14757        }
14758        if (dumpPackage == null) {
14759            pw.println("  mWakefulness="
14760                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14761            pw.println("  mSleepTokens=" + mSleepTokens);
14762            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14763                    + lockScreenShownToString());
14764            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14765            if (mRunningVoice != null) {
14766                pw.println("  mRunningVoice=" + mRunningVoice);
14767                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14768            }
14769        }
14770        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14771                || mOrigWaitForDebugger) {
14772            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14773                    || dumpPackage.equals(mOrigDebugApp)) {
14774                if (needSep) {
14775                    pw.println();
14776                    needSep = false;
14777                }
14778                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14779                        + " mDebugTransient=" + mDebugTransient
14780                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14781            }
14782        }
14783        if (mCurAppTimeTracker != null) {
14784            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14785        }
14786        if (mMemWatchProcesses.getMap().size() > 0) {
14787            pw.println("  Mem watch processes:");
14788            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14789                    = mMemWatchProcesses.getMap();
14790            for (int i=0; i<procs.size(); i++) {
14791                final String proc = procs.keyAt(i);
14792                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14793                for (int j=0; j<uids.size(); j++) {
14794                    if (needSep) {
14795                        pw.println();
14796                        needSep = false;
14797                    }
14798                    StringBuilder sb = new StringBuilder();
14799                    sb.append("    ").append(proc).append('/');
14800                    UserHandle.formatUid(sb, uids.keyAt(j));
14801                    Pair<Long, String> val = uids.valueAt(j);
14802                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14803                    if (val.second != null) {
14804                        sb.append(", report to ").append(val.second);
14805                    }
14806                    pw.println(sb.toString());
14807                }
14808            }
14809            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14810            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14811            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14812                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14813        }
14814        if (mTrackAllocationApp != null) {
14815            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14816                if (needSep) {
14817                    pw.println();
14818                    needSep = false;
14819                }
14820                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14821            }
14822        }
14823        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14824                || mProfileFd != null) {
14825            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14826                if (needSep) {
14827                    pw.println();
14828                    needSep = false;
14829                }
14830                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14831                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14832                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14833                        + mAutoStopProfiler);
14834                pw.println("  mProfileType=" + mProfileType);
14835            }
14836        }
14837        if (mNativeDebuggingApp != null) {
14838            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14839                if (needSep) {
14840                    pw.println();
14841                    needSep = false;
14842                }
14843                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14844            }
14845        }
14846        if (dumpPackage == null) {
14847            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14848                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14849                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14850            }
14851            if (mController != null) {
14852                pw.println("  mController=" + mController
14853                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14854            }
14855            if (dumpAll) {
14856                pw.println("  Total persistent processes: " + numPers);
14857                pw.println("  mProcessesReady=" + mProcessesReady
14858                        + " mSystemReady=" + mSystemReady
14859                        + " mBooted=" + mBooted
14860                        + " mFactoryTest=" + mFactoryTest);
14861                pw.println("  mBooting=" + mBooting
14862                        + " mCallFinishBooting=" + mCallFinishBooting
14863                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14864                pw.print("  mLastPowerCheckRealtime=");
14865                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14866                        pw.println("");
14867                pw.print("  mLastPowerCheckUptime=");
14868                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14869                        pw.println("");
14870                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14871                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14872                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14873                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14874                        + " (" + mLruProcesses.size() + " total)"
14875                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14876                        + " mNumServiceProcs=" + mNumServiceProcs
14877                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14878                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14879                        + " mLastMemoryLevel=" + mLastMemoryLevel
14880                        + " mLastNumProcesses=" + mLastNumProcesses);
14881                long now = SystemClock.uptimeMillis();
14882                pw.print("  mLastIdleTime=");
14883                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14884                        pw.print(" mLowRamSinceLastIdle=");
14885                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14886                        pw.println();
14887            }
14888        }
14889
14890        if (!printedAnything) {
14891            pw.println("  (nothing)");
14892        }
14893    }
14894
14895    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14896            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14897        if (mProcessesToGc.size() > 0) {
14898            boolean printed = false;
14899            long now = SystemClock.uptimeMillis();
14900            for (int i=0; i<mProcessesToGc.size(); i++) {
14901                ProcessRecord proc = mProcessesToGc.get(i);
14902                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14903                    continue;
14904                }
14905                if (!printed) {
14906                    if (needSep) pw.println();
14907                    needSep = true;
14908                    pw.println("  Processes that are waiting to GC:");
14909                    printed = true;
14910                }
14911                pw.print("    Process "); pw.println(proc);
14912                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14913                        pw.print(", last gced=");
14914                        pw.print(now-proc.lastRequestedGc);
14915                        pw.print(" ms ago, last lowMem=");
14916                        pw.print(now-proc.lastLowMemory);
14917                        pw.println(" ms ago");
14918
14919            }
14920        }
14921        return needSep;
14922    }
14923
14924    void printOomLevel(PrintWriter pw, String name, int adj) {
14925        pw.print("    ");
14926        if (adj >= 0) {
14927            pw.print(' ');
14928            if (adj < 10) pw.print(' ');
14929        } else {
14930            if (adj > -10) pw.print(' ');
14931        }
14932        pw.print(adj);
14933        pw.print(": ");
14934        pw.print(name);
14935        pw.print(" (");
14936        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14937        pw.println(")");
14938    }
14939
14940    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14941            int opti, boolean dumpAll) {
14942        boolean needSep = false;
14943
14944        if (mLruProcesses.size() > 0) {
14945            if (needSep) pw.println();
14946            needSep = true;
14947            pw.println("  OOM levels:");
14948            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14949            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14950            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14951            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14952            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14953            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14954            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14955            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14956            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14957            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14958            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14959            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14960            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14961            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14962
14963            if (needSep) pw.println();
14964            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14965                    pw.print(" total, non-act at ");
14966                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14967                    pw.print(", non-svc at ");
14968                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14969                    pw.println("):");
14970            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14971            needSep = true;
14972        }
14973
14974        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14975
14976        pw.println();
14977        pw.println("  mHomeProcess: " + mHomeProcess);
14978        pw.println("  mPreviousProcess: " + mPreviousProcess);
14979        if (mHeavyWeightProcess != null) {
14980            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14981        }
14982
14983        return true;
14984    }
14985
14986    /**
14987     * There are three ways to call this:
14988     *  - no provider specified: dump all the providers
14989     *  - a flattened component name that matched an existing provider was specified as the
14990     *    first arg: dump that one provider
14991     *  - the first arg isn't the flattened component name of an existing provider:
14992     *    dump all providers whose component contains the first arg as a substring
14993     */
14994    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14995            int opti, boolean dumpAll) {
14996        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14997    }
14998
14999    static class ItemMatcher {
15000        ArrayList<ComponentName> components;
15001        ArrayList<String> strings;
15002        ArrayList<Integer> objects;
15003        boolean all;
15004
15005        ItemMatcher() {
15006            all = true;
15007        }
15008
15009        void build(String name) {
15010            ComponentName componentName = ComponentName.unflattenFromString(name);
15011            if (componentName != null) {
15012                if (components == null) {
15013                    components = new ArrayList<ComponentName>();
15014                }
15015                components.add(componentName);
15016                all = false;
15017            } else {
15018                int objectId = 0;
15019                // Not a '/' separated full component name; maybe an object ID?
15020                try {
15021                    objectId = Integer.parseInt(name, 16);
15022                    if (objects == null) {
15023                        objects = new ArrayList<Integer>();
15024                    }
15025                    objects.add(objectId);
15026                    all = false;
15027                } catch (RuntimeException e) {
15028                    // Not an integer; just do string match.
15029                    if (strings == null) {
15030                        strings = new ArrayList<String>();
15031                    }
15032                    strings.add(name);
15033                    all = false;
15034                }
15035            }
15036        }
15037
15038        int build(String[] args, int opti) {
15039            for (; opti<args.length; opti++) {
15040                String name = args[opti];
15041                if ("--".equals(name)) {
15042                    return opti+1;
15043                }
15044                build(name);
15045            }
15046            return opti;
15047        }
15048
15049        boolean match(Object object, ComponentName comp) {
15050            if (all) {
15051                return true;
15052            }
15053            if (components != null) {
15054                for (int i=0; i<components.size(); i++) {
15055                    if (components.get(i).equals(comp)) {
15056                        return true;
15057                    }
15058                }
15059            }
15060            if (objects != null) {
15061                for (int i=0; i<objects.size(); i++) {
15062                    if (System.identityHashCode(object) == objects.get(i)) {
15063                        return true;
15064                    }
15065                }
15066            }
15067            if (strings != null) {
15068                String flat = comp.flattenToString();
15069                for (int i=0; i<strings.size(); i++) {
15070                    if (flat.contains(strings.get(i))) {
15071                        return true;
15072                    }
15073                }
15074            }
15075            return false;
15076        }
15077    }
15078
15079    /**
15080     * There are three things that cmd can be:
15081     *  - a flattened component name that matches an existing activity
15082     *  - the cmd arg isn't the flattened component name of an existing activity:
15083     *    dump all activity whose component contains the cmd as a substring
15084     *  - A hex number of the ActivityRecord object instance.
15085     */
15086    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15087            int opti, boolean dumpAll, boolean dumpVisibleStacks) {
15088        ArrayList<ActivityRecord> activities;
15089
15090        synchronized (this) {
15091            activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacks);
15092        }
15093
15094        if (activities.size() <= 0) {
15095            return false;
15096        }
15097
15098        String[] newArgs = new String[args.length - opti];
15099        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15100
15101        TaskRecord lastTask = null;
15102        boolean needSep = false;
15103        for (int i=activities.size()-1; i>=0; i--) {
15104            ActivityRecord r = activities.get(i);
15105            if (needSep) {
15106                pw.println();
15107            }
15108            needSep = true;
15109            synchronized (this) {
15110                if (lastTask != r.task) {
15111                    lastTask = r.task;
15112                    pw.print("TASK "); pw.print(lastTask.affinity);
15113                            pw.print(" id="); pw.print(lastTask.taskId);
15114                            pw.print(" userId="); pw.println(lastTask.userId);
15115                    if (dumpAll) {
15116                        lastTask.dump(pw, "  ");
15117                    }
15118                }
15119            }
15120            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
15121        }
15122        return true;
15123    }
15124
15125    /**
15126     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
15127     * there is a thread associated with the activity.
15128     */
15129    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
15130            final ActivityRecord r, String[] args, boolean dumpAll) {
15131        String innerPrefix = prefix + "  ";
15132        synchronized (this) {
15133            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
15134                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
15135                    pw.print(" pid=");
15136                    if (r.app != null) pw.println(r.app.pid);
15137                    else pw.println("(not running)");
15138            if (dumpAll) {
15139                r.dump(pw, innerPrefix);
15140            }
15141        }
15142        if (r.app != null && r.app.thread != null) {
15143            // flush anything that is already in the PrintWriter since the thread is going
15144            // to write to the file descriptor directly
15145            pw.flush();
15146            try {
15147                TransferPipe tp = new TransferPipe();
15148                try {
15149                    r.app.thread.dumpActivity(tp.getWriteFd(),
15150                            r.appToken, innerPrefix, args);
15151                    tp.go(fd);
15152                } finally {
15153                    tp.kill();
15154                }
15155            } catch (IOException e) {
15156                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
15157            } catch (RemoteException e) {
15158                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
15159            }
15160        }
15161    }
15162
15163    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15164            int opti, boolean dumpAll, String dumpPackage) {
15165        boolean needSep = false;
15166        boolean onlyHistory = false;
15167        boolean printedAnything = false;
15168
15169        if ("history".equals(dumpPackage)) {
15170            if (opti < args.length && "-s".equals(args[opti])) {
15171                dumpAll = false;
15172            }
15173            onlyHistory = true;
15174            dumpPackage = null;
15175        }
15176
15177        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
15178        if (!onlyHistory && dumpAll) {
15179            if (mRegisteredReceivers.size() > 0) {
15180                boolean printed = false;
15181                Iterator it = mRegisteredReceivers.values().iterator();
15182                while (it.hasNext()) {
15183                    ReceiverList r = (ReceiverList)it.next();
15184                    if (dumpPackage != null && (r.app == null ||
15185                            !dumpPackage.equals(r.app.info.packageName))) {
15186                        continue;
15187                    }
15188                    if (!printed) {
15189                        pw.println("  Registered Receivers:");
15190                        needSep = true;
15191                        printed = true;
15192                        printedAnything = true;
15193                    }
15194                    pw.print("  * "); pw.println(r);
15195                    r.dump(pw, "    ");
15196                }
15197            }
15198
15199            if (mReceiverResolver.dump(pw, needSep ?
15200                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
15201                    "    ", dumpPackage, false, false)) {
15202                needSep = true;
15203                printedAnything = true;
15204            }
15205        }
15206
15207        for (BroadcastQueue q : mBroadcastQueues) {
15208            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
15209            printedAnything |= needSep;
15210        }
15211
15212        needSep = true;
15213
15214        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15215            for (int user=0; user<mStickyBroadcasts.size(); user++) {
15216                if (needSep) {
15217                    pw.println();
15218                }
15219                needSep = true;
15220                printedAnything = true;
15221                pw.print("  Sticky broadcasts for user ");
15222                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15223                StringBuilder sb = new StringBuilder(128);
15224                for (Map.Entry<String, ArrayList<Intent>> ent
15225                        : mStickyBroadcasts.valueAt(user).entrySet()) {
15226                    pw.print("  * Sticky action "); pw.print(ent.getKey());
15227                    if (dumpAll) {
15228                        pw.println(":");
15229                        ArrayList<Intent> intents = ent.getValue();
15230                        final int N = intents.size();
15231                        for (int i=0; i<N; i++) {
15232                            sb.setLength(0);
15233                            sb.append("    Intent: ");
15234                            intents.get(i).toShortString(sb, false, true, false, false);
15235                            pw.println(sb.toString());
15236                            Bundle bundle = intents.get(i).getExtras();
15237                            if (bundle != null) {
15238                                pw.print("      ");
15239                                pw.println(bundle.toString());
15240                            }
15241                        }
15242                    } else {
15243                        pw.println("");
15244                    }
15245                }
15246            }
15247        }
15248
15249        if (!onlyHistory && dumpAll) {
15250            pw.println();
15251            for (BroadcastQueue queue : mBroadcastQueues) {
15252                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
15253                        + queue.mBroadcastsScheduled);
15254            }
15255            pw.println("  mHandler:");
15256            mHandler.dump(new PrintWriterPrinter(pw), "    ");
15257            needSep = true;
15258            printedAnything = true;
15259        }
15260
15261        if (!printedAnything) {
15262            pw.println("  (nothing)");
15263        }
15264    }
15265
15266    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15267            int opti, boolean dumpAll, String dumpPackage) {
15268        if (mCurBroadcastStats == null) {
15269            return;
15270        }
15271
15272        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15273        final long now = SystemClock.elapsedRealtime();
15274        if (mLastBroadcastStats != null) {
15275            pw.print("  Last stats (from ");
15276            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15277            pw.print(" to ");
15278            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15279            pw.print(", ");
15280            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15281                    - mLastBroadcastStats.mStartUptime, pw);
15282            pw.println(" uptime):");
15283            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15284                pw.println("    (nothing)");
15285            }
15286            pw.println();
15287        }
15288        pw.print("  Current stats (from ");
15289        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15290        pw.print(" to now, ");
15291        TimeUtils.formatDuration(SystemClock.uptimeMillis()
15292                - mCurBroadcastStats.mStartUptime, pw);
15293        pw.println(" uptime):");
15294        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15295            pw.println("    (nothing)");
15296        }
15297    }
15298
15299    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15300            int opti, boolean fullCheckin, String dumpPackage) {
15301        if (mCurBroadcastStats == null) {
15302            return;
15303        }
15304
15305        if (mLastBroadcastStats != null) {
15306            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15307            if (fullCheckin) {
15308                mLastBroadcastStats = null;
15309                return;
15310            }
15311        }
15312        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15313        if (fullCheckin) {
15314            mCurBroadcastStats = null;
15315        }
15316    }
15317
15318    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15319            int opti, boolean dumpAll, String dumpPackage) {
15320        boolean needSep;
15321        boolean printedAnything = false;
15322
15323        ItemMatcher matcher = new ItemMatcher();
15324        matcher.build(args, opti);
15325
15326        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15327
15328        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15329        printedAnything |= needSep;
15330
15331        if (mLaunchingProviders.size() > 0) {
15332            boolean printed = false;
15333            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15334                ContentProviderRecord r = mLaunchingProviders.get(i);
15335                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15336                    continue;
15337                }
15338                if (!printed) {
15339                    if (needSep) pw.println();
15340                    needSep = true;
15341                    pw.println("  Launching content providers:");
15342                    printed = true;
15343                    printedAnything = true;
15344                }
15345                pw.print("  Launching #"); pw.print(i); pw.print(": ");
15346                        pw.println(r);
15347            }
15348        }
15349
15350        if (!printedAnything) {
15351            pw.println("  (nothing)");
15352        }
15353    }
15354
15355    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15356            int opti, boolean dumpAll, String dumpPackage) {
15357        boolean needSep = false;
15358        boolean printedAnything = false;
15359
15360        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15361
15362        if (mGrantedUriPermissions.size() > 0) {
15363            boolean printed = false;
15364            int dumpUid = -2;
15365            if (dumpPackage != null) {
15366                try {
15367                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15368                            MATCH_UNINSTALLED_PACKAGES, 0);
15369                } catch (NameNotFoundException e) {
15370                    dumpUid = -1;
15371                }
15372            }
15373            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15374                int uid = mGrantedUriPermissions.keyAt(i);
15375                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15376                    continue;
15377                }
15378                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15379                if (!printed) {
15380                    if (needSep) pw.println();
15381                    needSep = true;
15382                    pw.println("  Granted Uri Permissions:");
15383                    printed = true;
15384                    printedAnything = true;
15385                }
15386                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15387                for (UriPermission perm : perms.values()) {
15388                    pw.print("    "); pw.println(perm);
15389                    if (dumpAll) {
15390                        perm.dump(pw, "      ");
15391                    }
15392                }
15393            }
15394        }
15395
15396        if (!printedAnything) {
15397            pw.println("  (nothing)");
15398        }
15399    }
15400
15401    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15402            int opti, boolean dumpAll, String dumpPackage) {
15403        boolean printed = false;
15404
15405        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15406
15407        if (mIntentSenderRecords.size() > 0) {
15408            Iterator<WeakReference<PendingIntentRecord>> it
15409                    = mIntentSenderRecords.values().iterator();
15410            while (it.hasNext()) {
15411                WeakReference<PendingIntentRecord> ref = it.next();
15412                PendingIntentRecord rec = ref != null ? ref.get(): null;
15413                if (dumpPackage != null && (rec == null
15414                        || !dumpPackage.equals(rec.key.packageName))) {
15415                    continue;
15416                }
15417                printed = true;
15418                if (rec != null) {
15419                    pw.print("  * "); pw.println(rec);
15420                    if (dumpAll) {
15421                        rec.dump(pw, "    ");
15422                    }
15423                } else {
15424                    pw.print("  * "); pw.println(ref);
15425                }
15426            }
15427        }
15428
15429        if (!printed) {
15430            pw.println("  (nothing)");
15431        }
15432    }
15433
15434    private static final int dumpProcessList(PrintWriter pw,
15435            ActivityManagerService service, List list,
15436            String prefix, String normalLabel, String persistentLabel,
15437            String dumpPackage) {
15438        int numPers = 0;
15439        final int N = list.size()-1;
15440        for (int i=N; i>=0; i--) {
15441            ProcessRecord r = (ProcessRecord)list.get(i);
15442            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15443                continue;
15444            }
15445            pw.println(String.format("%s%s #%2d: %s",
15446                    prefix, (r.persistent ? persistentLabel : normalLabel),
15447                    i, r.toString()));
15448            if (r.persistent) {
15449                numPers++;
15450            }
15451        }
15452        return numPers;
15453    }
15454
15455    private static final boolean dumpProcessOomList(PrintWriter pw,
15456            ActivityManagerService service, List<ProcessRecord> origList,
15457            String prefix, String normalLabel, String persistentLabel,
15458            boolean inclDetails, String dumpPackage) {
15459
15460        ArrayList<Pair<ProcessRecord, Integer>> list
15461                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15462        for (int i=0; i<origList.size(); i++) {
15463            ProcessRecord r = origList.get(i);
15464            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15465                continue;
15466            }
15467            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15468        }
15469
15470        if (list.size() <= 0) {
15471            return false;
15472        }
15473
15474        Comparator<Pair<ProcessRecord, Integer>> comparator
15475                = new Comparator<Pair<ProcessRecord, Integer>>() {
15476            @Override
15477            public int compare(Pair<ProcessRecord, Integer> object1,
15478                    Pair<ProcessRecord, Integer> object2) {
15479                if (object1.first.setAdj != object2.first.setAdj) {
15480                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15481                }
15482                if (object1.first.setProcState != object2.first.setProcState) {
15483                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15484                }
15485                if (object1.second.intValue() != object2.second.intValue()) {
15486                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15487                }
15488                return 0;
15489            }
15490        };
15491
15492        Collections.sort(list, comparator);
15493
15494        final long curRealtime = SystemClock.elapsedRealtime();
15495        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15496        final long curUptime = SystemClock.uptimeMillis();
15497        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15498
15499        for (int i=list.size()-1; i>=0; i--) {
15500            ProcessRecord r = list.get(i).first;
15501            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15502            char schedGroup;
15503            switch (r.setSchedGroup) {
15504                case ProcessList.SCHED_GROUP_BACKGROUND:
15505                    schedGroup = 'B';
15506                    break;
15507                case ProcessList.SCHED_GROUP_DEFAULT:
15508                    schedGroup = 'F';
15509                    break;
15510                case ProcessList.SCHED_GROUP_TOP_APP:
15511                    schedGroup = 'T';
15512                    break;
15513                default:
15514                    schedGroup = '?';
15515                    break;
15516            }
15517            char foreground;
15518            if (r.foregroundActivities) {
15519                foreground = 'A';
15520            } else if (r.foregroundServices) {
15521                foreground = 'S';
15522            } else {
15523                foreground = ' ';
15524            }
15525            String procState = ProcessList.makeProcStateString(r.curProcState);
15526            pw.print(prefix);
15527            pw.print(r.persistent ? persistentLabel : normalLabel);
15528            pw.print(" #");
15529            int num = (origList.size()-1)-list.get(i).second;
15530            if (num < 10) pw.print(' ');
15531            pw.print(num);
15532            pw.print(": ");
15533            pw.print(oomAdj);
15534            pw.print(' ');
15535            pw.print(schedGroup);
15536            pw.print('/');
15537            pw.print(foreground);
15538            pw.print('/');
15539            pw.print(procState);
15540            pw.print(" trm:");
15541            if (r.trimMemoryLevel < 10) pw.print(' ');
15542            pw.print(r.trimMemoryLevel);
15543            pw.print(' ');
15544            pw.print(r.toShortString());
15545            pw.print(" (");
15546            pw.print(r.adjType);
15547            pw.println(')');
15548            if (r.adjSource != null || r.adjTarget != null) {
15549                pw.print(prefix);
15550                pw.print("    ");
15551                if (r.adjTarget instanceof ComponentName) {
15552                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15553                } else if (r.adjTarget != null) {
15554                    pw.print(r.adjTarget.toString());
15555                } else {
15556                    pw.print("{null}");
15557                }
15558                pw.print("<=");
15559                if (r.adjSource instanceof ProcessRecord) {
15560                    pw.print("Proc{");
15561                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15562                    pw.println("}");
15563                } else if (r.adjSource != null) {
15564                    pw.println(r.adjSource.toString());
15565                } else {
15566                    pw.println("{null}");
15567                }
15568            }
15569            if (inclDetails) {
15570                pw.print(prefix);
15571                pw.print("    ");
15572                pw.print("oom: max="); pw.print(r.maxAdj);
15573                pw.print(" curRaw="); pw.print(r.curRawAdj);
15574                pw.print(" setRaw="); pw.print(r.setRawAdj);
15575                pw.print(" cur="); pw.print(r.curAdj);
15576                pw.print(" set="); pw.println(r.setAdj);
15577                pw.print(prefix);
15578                pw.print("    ");
15579                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15580                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15581                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15582                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15583                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15584                pw.println();
15585                pw.print(prefix);
15586                pw.print("    ");
15587                pw.print("cached="); pw.print(r.cached);
15588                pw.print(" empty="); pw.print(r.empty);
15589                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15590
15591                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15592                    if (r.lastWakeTime != 0) {
15593                        long wtime;
15594                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15595                        synchronized (stats) {
15596                            wtime = stats.getProcessWakeTime(r.info.uid,
15597                                    r.pid, curRealtime);
15598                        }
15599                        long timeUsed = wtime - r.lastWakeTime;
15600                        pw.print(prefix);
15601                        pw.print("    ");
15602                        pw.print("keep awake over ");
15603                        TimeUtils.formatDuration(realtimeSince, pw);
15604                        pw.print(" used ");
15605                        TimeUtils.formatDuration(timeUsed, pw);
15606                        pw.print(" (");
15607                        pw.print((timeUsed*100)/realtimeSince);
15608                        pw.println("%)");
15609                    }
15610                    if (r.lastCpuTime != 0) {
15611                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15612                        pw.print(prefix);
15613                        pw.print("    ");
15614                        pw.print("run cpu over ");
15615                        TimeUtils.formatDuration(uptimeSince, pw);
15616                        pw.print(" used ");
15617                        TimeUtils.formatDuration(timeUsed, pw);
15618                        pw.print(" (");
15619                        pw.print((timeUsed*100)/uptimeSince);
15620                        pw.println("%)");
15621                    }
15622                }
15623            }
15624        }
15625        return true;
15626    }
15627
15628    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15629            String[] args) {
15630        ArrayList<ProcessRecord> procs;
15631        synchronized (this) {
15632            if (args != null && args.length > start
15633                    && args[start].charAt(0) != '-') {
15634                procs = new ArrayList<ProcessRecord>();
15635                int pid = -1;
15636                try {
15637                    pid = Integer.parseInt(args[start]);
15638                } catch (NumberFormatException e) {
15639                }
15640                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15641                    ProcessRecord proc = mLruProcesses.get(i);
15642                    if (proc.pid == pid) {
15643                        procs.add(proc);
15644                    } else if (allPkgs && proc.pkgList != null
15645                            && proc.pkgList.containsKey(args[start])) {
15646                        procs.add(proc);
15647                    } else if (proc.processName.equals(args[start])) {
15648                        procs.add(proc);
15649                    }
15650                }
15651                if (procs.size() <= 0) {
15652                    return null;
15653                }
15654            } else {
15655                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15656            }
15657        }
15658        return procs;
15659    }
15660
15661    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15662            PrintWriter pw, String[] args) {
15663        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15664        if (procs == null) {
15665            pw.println("No process found for: " + args[0]);
15666            return;
15667        }
15668
15669        long uptime = SystemClock.uptimeMillis();
15670        long realtime = SystemClock.elapsedRealtime();
15671        pw.println("Applications Graphics Acceleration Info:");
15672        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15673
15674        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15675            ProcessRecord r = procs.get(i);
15676            if (r.thread != null) {
15677                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15678                pw.flush();
15679                try {
15680                    TransferPipe tp = new TransferPipe();
15681                    try {
15682                        r.thread.dumpGfxInfo(tp.getWriteFd(), args);
15683                        tp.go(fd);
15684                    } finally {
15685                        tp.kill();
15686                    }
15687                } catch (IOException e) {
15688                    pw.println("Failure while dumping the app: " + r);
15689                    pw.flush();
15690                } catch (RemoteException e) {
15691                    pw.println("Got a RemoteException while dumping the app " + r);
15692                    pw.flush();
15693                }
15694            }
15695        }
15696    }
15697
15698    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15699        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15700        if (procs == null) {
15701            pw.println("No process found for: " + args[0]);
15702            return;
15703        }
15704
15705        pw.println("Applications Database Info:");
15706
15707        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15708            ProcessRecord r = procs.get(i);
15709            if (r.thread != null) {
15710                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15711                pw.flush();
15712                try {
15713                    TransferPipe tp = new TransferPipe();
15714                    try {
15715                        r.thread.dumpDbInfo(tp.getWriteFd(), args);
15716                        tp.go(fd);
15717                    } finally {
15718                        tp.kill();
15719                    }
15720                } catch (IOException e) {
15721                    pw.println("Failure while dumping the app: " + r);
15722                    pw.flush();
15723                } catch (RemoteException e) {
15724                    pw.println("Got a RemoteException while dumping the app " + r);
15725                    pw.flush();
15726                }
15727            }
15728        }
15729    }
15730
15731    final static class MemItem {
15732        final boolean isProc;
15733        final String label;
15734        final String shortLabel;
15735        final long pss;
15736        final long swapPss;
15737        final int id;
15738        final boolean hasActivities;
15739        ArrayList<MemItem> subitems;
15740
15741        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15742                boolean _hasActivities) {
15743            isProc = true;
15744            label = _label;
15745            shortLabel = _shortLabel;
15746            pss = _pss;
15747            swapPss = _swapPss;
15748            id = _id;
15749            hasActivities = _hasActivities;
15750        }
15751
15752        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15753            isProc = false;
15754            label = _label;
15755            shortLabel = _shortLabel;
15756            pss = _pss;
15757            swapPss = _swapPss;
15758            id = _id;
15759            hasActivities = false;
15760        }
15761    }
15762
15763    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15764            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15765        if (sort && !isCompact) {
15766            Collections.sort(items, new Comparator<MemItem>() {
15767                @Override
15768                public int compare(MemItem lhs, MemItem rhs) {
15769                    if (lhs.pss < rhs.pss) {
15770                        return 1;
15771                    } else if (lhs.pss > rhs.pss) {
15772                        return -1;
15773                    }
15774                    return 0;
15775                }
15776            });
15777        }
15778
15779        for (int i=0; i<items.size(); i++) {
15780            MemItem mi = items.get(i);
15781            if (!isCompact) {
15782                if (dumpSwapPss) {
15783                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15784                            mi.label, stringifyKBSize(mi.swapPss));
15785                } else {
15786                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15787                }
15788            } else if (mi.isProc) {
15789                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15790                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15791                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15792                pw.println(mi.hasActivities ? ",a" : ",e");
15793            } else {
15794                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15795                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15796            }
15797            if (mi.subitems != null) {
15798                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15799                        true, isCompact, dumpSwapPss);
15800            }
15801        }
15802    }
15803
15804    // These are in KB.
15805    static final long[] DUMP_MEM_BUCKETS = new long[] {
15806        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15807        120*1024, 160*1024, 200*1024,
15808        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15809        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15810    };
15811
15812    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15813            boolean stackLike) {
15814        int start = label.lastIndexOf('.');
15815        if (start >= 0) start++;
15816        else start = 0;
15817        int end = label.length();
15818        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15819            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15820                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15821                out.append(bucket);
15822                out.append(stackLike ? "MB." : "MB ");
15823                out.append(label, start, end);
15824                return;
15825            }
15826        }
15827        out.append(memKB/1024);
15828        out.append(stackLike ? "MB." : "MB ");
15829        out.append(label, start, end);
15830    }
15831
15832    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15833            ProcessList.NATIVE_ADJ,
15834            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15835            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15836            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15837            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15838            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15839            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15840    };
15841    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15842            "Native",
15843            "System", "Persistent", "Persistent Service", "Foreground",
15844            "Visible", "Perceptible",
15845            "Heavy Weight", "Backup",
15846            "A Services", "Home",
15847            "Previous", "B Services", "Cached"
15848    };
15849    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15850            "native",
15851            "sys", "pers", "persvc", "fore",
15852            "vis", "percept",
15853            "heavy", "backup",
15854            "servicea", "home",
15855            "prev", "serviceb", "cached"
15856    };
15857
15858    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15859            long realtime, boolean isCheckinRequest, boolean isCompact) {
15860        if (isCompact) {
15861            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15862        }
15863        if (isCheckinRequest || isCompact) {
15864            // short checkin version
15865            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15866        } else {
15867            pw.println("Applications Memory Usage (in Kilobytes):");
15868            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15869        }
15870    }
15871
15872    private static final int KSM_SHARED = 0;
15873    private static final int KSM_SHARING = 1;
15874    private static final int KSM_UNSHARED = 2;
15875    private static final int KSM_VOLATILE = 3;
15876
15877    private final long[] getKsmInfo() {
15878        long[] longOut = new long[4];
15879        final int[] SINGLE_LONG_FORMAT = new int[] {
15880            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15881        };
15882        long[] longTmp = new long[1];
15883        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15884                SINGLE_LONG_FORMAT, null, longTmp, null);
15885        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15886        longTmp[0] = 0;
15887        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15888                SINGLE_LONG_FORMAT, null, longTmp, null);
15889        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15890        longTmp[0] = 0;
15891        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15892                SINGLE_LONG_FORMAT, null, longTmp, null);
15893        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15894        longTmp[0] = 0;
15895        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15896                SINGLE_LONG_FORMAT, null, longTmp, null);
15897        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15898        return longOut;
15899    }
15900
15901    private static String stringifySize(long size, int order) {
15902        Locale locale = Locale.US;
15903        switch (order) {
15904            case 1:
15905                return String.format(locale, "%,13d", size);
15906            case 1024:
15907                return String.format(locale, "%,9dK", size / 1024);
15908            case 1024 * 1024:
15909                return String.format(locale, "%,5dM", size / 1024 / 1024);
15910            case 1024 * 1024 * 1024:
15911                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15912            default:
15913                throw new IllegalArgumentException("Invalid size order");
15914        }
15915    }
15916
15917    private static String stringifyKBSize(long size) {
15918        return stringifySize(size * 1024, 1024);
15919    }
15920
15921    // Update this version number in case you change the 'compact' format
15922    private static final int MEMINFO_COMPACT_VERSION = 1;
15923
15924    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15925            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15926        boolean dumpDetails = false;
15927        boolean dumpFullDetails = false;
15928        boolean dumpDalvik = false;
15929        boolean dumpSummaryOnly = false;
15930        boolean dumpUnreachable = false;
15931        boolean oomOnly = false;
15932        boolean isCompact = false;
15933        boolean localOnly = false;
15934        boolean packages = false;
15935        boolean isCheckinRequest = false;
15936        boolean dumpSwapPss = false;
15937
15938        int opti = 0;
15939        while (opti < args.length) {
15940            String opt = args[opti];
15941            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15942                break;
15943            }
15944            opti++;
15945            if ("-a".equals(opt)) {
15946                dumpDetails = true;
15947                dumpFullDetails = true;
15948                dumpDalvik = true;
15949                dumpSwapPss = true;
15950            } else if ("-d".equals(opt)) {
15951                dumpDalvik = true;
15952            } else if ("-c".equals(opt)) {
15953                isCompact = true;
15954            } else if ("-s".equals(opt)) {
15955                dumpDetails = true;
15956                dumpSummaryOnly = true;
15957            } else if ("-S".equals(opt)) {
15958                dumpSwapPss = true;
15959            } else if ("--unreachable".equals(opt)) {
15960                dumpUnreachable = true;
15961            } else if ("--oom".equals(opt)) {
15962                oomOnly = true;
15963            } else if ("--local".equals(opt)) {
15964                localOnly = true;
15965            } else if ("--package".equals(opt)) {
15966                packages = true;
15967            } else if ("--checkin".equals(opt)) {
15968                isCheckinRequest = true;
15969
15970            } else if ("-h".equals(opt)) {
15971                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15972                pw.println("  -a: include all available information for each process.");
15973                pw.println("  -d: include dalvik details.");
15974                pw.println("  -c: dump in a compact machine-parseable representation.");
15975                pw.println("  -s: dump only summary of application memory usage.");
15976                pw.println("  -S: dump also SwapPss.");
15977                pw.println("  --oom: only show processes organized by oom adj.");
15978                pw.println("  --local: only collect details locally, don't call process.");
15979                pw.println("  --package: interpret process arg as package, dumping all");
15980                pw.println("             processes that have loaded that package.");
15981                pw.println("  --checkin: dump data for a checkin");
15982                pw.println("If [process] is specified it can be the name or ");
15983                pw.println("pid of a specific process to dump.");
15984                return;
15985            } else {
15986                pw.println("Unknown argument: " + opt + "; use -h for help");
15987            }
15988        }
15989
15990        long uptime = SystemClock.uptimeMillis();
15991        long realtime = SystemClock.elapsedRealtime();
15992        final long[] tmpLong = new long[1];
15993
15994        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15995        if (procs == null) {
15996            // No Java processes.  Maybe they want to print a native process.
15997            if (args != null && args.length > opti
15998                    && args[opti].charAt(0) != '-') {
15999                ArrayList<ProcessCpuTracker.Stats> nativeProcs
16000                        = new ArrayList<ProcessCpuTracker.Stats>();
16001                updateCpuStatsNow();
16002                int findPid = -1;
16003                try {
16004                    findPid = Integer.parseInt(args[opti]);
16005                } catch (NumberFormatException e) {
16006                }
16007                synchronized (mProcessCpuTracker) {
16008                    final int N = mProcessCpuTracker.countStats();
16009                    for (int i=0; i<N; i++) {
16010                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16011                        if (st.pid == findPid || (st.baseName != null
16012                                && st.baseName.equals(args[opti]))) {
16013                            nativeProcs.add(st);
16014                        }
16015                    }
16016                }
16017                if (nativeProcs.size() > 0) {
16018                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
16019                            isCompact);
16020                    Debug.MemoryInfo mi = null;
16021                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
16022                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
16023                        final int pid = r.pid;
16024                        if (!isCheckinRequest && dumpDetails) {
16025                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
16026                        }
16027                        if (mi == null) {
16028                            mi = new Debug.MemoryInfo();
16029                        }
16030                        if (dumpDetails || (!brief && !oomOnly)) {
16031                            Debug.getMemoryInfo(pid, mi);
16032                        } else {
16033                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16034                            mi.dalvikPrivateDirty = (int)tmpLong[0];
16035                        }
16036                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16037                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
16038                        if (isCheckinRequest) {
16039                            pw.println();
16040                        }
16041                    }
16042                    return;
16043                }
16044            }
16045            pw.println("No process found for: " + args[opti]);
16046            return;
16047        }
16048
16049        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
16050            dumpDetails = true;
16051        }
16052
16053        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
16054
16055        String[] innerArgs = new String[args.length-opti];
16056        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
16057
16058        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
16059        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
16060        long nativePss = 0;
16061        long nativeSwapPss = 0;
16062        long dalvikPss = 0;
16063        long dalvikSwapPss = 0;
16064        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16065                EmptyArray.LONG;
16066        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16067                EmptyArray.LONG;
16068        long otherPss = 0;
16069        long otherSwapPss = 0;
16070        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16071        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16072
16073        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16074        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16075        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
16076                new ArrayList[DUMP_MEM_OOM_LABEL.length];
16077
16078        long totalPss = 0;
16079        long totalSwapPss = 0;
16080        long cachedPss = 0;
16081        long cachedSwapPss = 0;
16082        boolean hasSwapPss = false;
16083
16084        Debug.MemoryInfo mi = null;
16085        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16086            final ProcessRecord r = procs.get(i);
16087            final IApplicationThread thread;
16088            final int pid;
16089            final int oomAdj;
16090            final boolean hasActivities;
16091            synchronized (this) {
16092                thread = r.thread;
16093                pid = r.pid;
16094                oomAdj = r.getSetAdjWithServices();
16095                hasActivities = r.activities.size() > 0;
16096            }
16097            if (thread != null) {
16098                if (!isCheckinRequest && dumpDetails) {
16099                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
16100                }
16101                if (mi == null) {
16102                    mi = new Debug.MemoryInfo();
16103                }
16104                if (dumpDetails || (!brief && !oomOnly)) {
16105                    Debug.getMemoryInfo(pid, mi);
16106                    hasSwapPss = mi.hasSwappedOutPss;
16107                } else {
16108                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16109                    mi.dalvikPrivateDirty = (int)tmpLong[0];
16110                }
16111                if (dumpDetails) {
16112                    if (localOnly) {
16113                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16114                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
16115                        if (isCheckinRequest) {
16116                            pw.println();
16117                        }
16118                    } else {
16119                        pw.flush();
16120                        try {
16121                            TransferPipe tp = new TransferPipe();
16122                            try {
16123                                thread.dumpMemInfo(tp.getWriteFd(),
16124                                        mi, isCheckinRequest, dumpFullDetails,
16125                                        dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
16126                                tp.go(fd);
16127                            } finally {
16128                                tp.kill();
16129                            }
16130                        } catch (IOException e) {
16131                            if (!isCheckinRequest) {
16132                                pw.println("Got IoException!");
16133                                pw.flush();
16134                            }
16135                        } catch (RemoteException e) {
16136                            if (!isCheckinRequest) {
16137                                pw.println("Got RemoteException!");
16138                                pw.flush();
16139                            }
16140                        }
16141                    }
16142                }
16143
16144                final long myTotalPss = mi.getTotalPss();
16145                final long myTotalUss = mi.getTotalUss();
16146                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16147
16148                synchronized (this) {
16149                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
16150                        // Record this for posterity if the process has been stable.
16151                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
16152                    }
16153                }
16154
16155                if (!isCheckinRequest && mi != null) {
16156                    totalPss += myTotalPss;
16157                    totalSwapPss += myTotalSwapPss;
16158                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
16159                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
16160                            myTotalSwapPss, pid, hasActivities);
16161                    procMems.add(pssItem);
16162                    procMemsMap.put(pid, pssItem);
16163
16164                    nativePss += mi.nativePss;
16165                    nativeSwapPss += mi.nativeSwappedOutPss;
16166                    dalvikPss += mi.dalvikPss;
16167                    dalvikSwapPss += mi.dalvikSwappedOutPss;
16168                    for (int j=0; j<dalvikSubitemPss.length; j++) {
16169                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16170                        dalvikSubitemSwapPss[j] +=
16171                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16172                    }
16173                    otherPss += mi.otherPss;
16174                    otherSwapPss += mi.otherSwappedOutPss;
16175                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16176                        long mem = mi.getOtherPss(j);
16177                        miscPss[j] += mem;
16178                        otherPss -= mem;
16179                        mem = mi.getOtherSwappedOutPss(j);
16180                        miscSwapPss[j] += mem;
16181                        otherSwapPss -= mem;
16182                    }
16183
16184                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16185                        cachedPss += myTotalPss;
16186                        cachedSwapPss += myTotalSwapPss;
16187                    }
16188
16189                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
16190                        if (oomIndex == (oomPss.length - 1)
16191                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
16192                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
16193                            oomPss[oomIndex] += myTotalPss;
16194                            oomSwapPss[oomIndex] += myTotalSwapPss;
16195                            if (oomProcs[oomIndex] == null) {
16196                                oomProcs[oomIndex] = new ArrayList<MemItem>();
16197                            }
16198                            oomProcs[oomIndex].add(pssItem);
16199                            break;
16200                        }
16201                    }
16202                }
16203            }
16204        }
16205
16206        long nativeProcTotalPss = 0;
16207
16208        if (!isCheckinRequest && procs.size() > 1 && !packages) {
16209            // If we are showing aggregations, also look for native processes to
16210            // include so that our aggregations are more accurate.
16211            updateCpuStatsNow();
16212            mi = null;
16213            synchronized (mProcessCpuTracker) {
16214                final int N = mProcessCpuTracker.countStats();
16215                for (int i=0; i<N; i++) {
16216                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16217                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
16218                        if (mi == null) {
16219                            mi = new Debug.MemoryInfo();
16220                        }
16221                        if (!brief && !oomOnly) {
16222                            Debug.getMemoryInfo(st.pid, mi);
16223                        } else {
16224                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
16225                            mi.nativePrivateDirty = (int)tmpLong[0];
16226                        }
16227
16228                        final long myTotalPss = mi.getTotalPss();
16229                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16230                        totalPss += myTotalPss;
16231                        nativeProcTotalPss += myTotalPss;
16232
16233                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16234                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16235                        procMems.add(pssItem);
16236
16237                        nativePss += mi.nativePss;
16238                        nativeSwapPss += mi.nativeSwappedOutPss;
16239                        dalvikPss += mi.dalvikPss;
16240                        dalvikSwapPss += mi.dalvikSwappedOutPss;
16241                        for (int j=0; j<dalvikSubitemPss.length; j++) {
16242                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16243                            dalvikSubitemSwapPss[j] +=
16244                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16245                        }
16246                        otherPss += mi.otherPss;
16247                        otherSwapPss += mi.otherSwappedOutPss;
16248                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16249                            long mem = mi.getOtherPss(j);
16250                            miscPss[j] += mem;
16251                            otherPss -= mem;
16252                            mem = mi.getOtherSwappedOutPss(j);
16253                            miscSwapPss[j] += mem;
16254                            otherSwapPss -= mem;
16255                        }
16256                        oomPss[0] += myTotalPss;
16257                        oomSwapPss[0] += myTotalSwapPss;
16258                        if (oomProcs[0] == null) {
16259                            oomProcs[0] = new ArrayList<MemItem>();
16260                        }
16261                        oomProcs[0].add(pssItem);
16262                    }
16263                }
16264            }
16265
16266            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16267
16268            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16269            final MemItem dalvikItem =
16270                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16271            if (dalvikSubitemPss.length > 0) {
16272                dalvikItem.subitems = new ArrayList<MemItem>();
16273                for (int j=0; j<dalvikSubitemPss.length; j++) {
16274                    final String name = Debug.MemoryInfo.getOtherLabel(
16275                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
16276                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16277                                    dalvikSubitemSwapPss[j], j));
16278                }
16279            }
16280            catMems.add(dalvikItem);
16281            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16282            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16283                String label = Debug.MemoryInfo.getOtherLabel(j);
16284                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16285            }
16286
16287            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16288            for (int j=0; j<oomPss.length; j++) {
16289                if (oomPss[j] != 0) {
16290                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16291                            : DUMP_MEM_OOM_LABEL[j];
16292                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16293                            DUMP_MEM_OOM_ADJ[j]);
16294                    item.subitems = oomProcs[j];
16295                    oomMems.add(item);
16296                }
16297            }
16298
16299            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16300            if (!brief && !oomOnly && !isCompact) {
16301                pw.println();
16302                pw.println("Total PSS by process:");
16303                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
16304                pw.println();
16305            }
16306            if (!isCompact) {
16307                pw.println("Total PSS by OOM adjustment:");
16308            }
16309            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
16310            if (!brief && !oomOnly) {
16311                PrintWriter out = categoryPw != null ? categoryPw : pw;
16312                if (!isCompact) {
16313                    out.println();
16314                    out.println("Total PSS by category:");
16315                }
16316                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
16317            }
16318            if (!isCompact) {
16319                pw.println();
16320            }
16321            MemInfoReader memInfo = new MemInfoReader();
16322            memInfo.readMemInfo();
16323            if (nativeProcTotalPss > 0) {
16324                synchronized (this) {
16325                    final long cachedKb = memInfo.getCachedSizeKb();
16326                    final long freeKb = memInfo.getFreeSizeKb();
16327                    final long zramKb = memInfo.getZramTotalSizeKb();
16328                    final long kernelKb = memInfo.getKernelUsedSizeKb();
16329                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16330                            kernelKb*1024, nativeProcTotalPss*1024);
16331                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16332                            nativeProcTotalPss);
16333                }
16334            }
16335            if (!brief) {
16336                if (!isCompact) {
16337                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16338                    pw.print(" (status ");
16339                    switch (mLastMemoryLevel) {
16340                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16341                            pw.println("normal)");
16342                            break;
16343                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16344                            pw.println("moderate)");
16345                            break;
16346                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
16347                            pw.println("low)");
16348                            break;
16349                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16350                            pw.println("critical)");
16351                            break;
16352                        default:
16353                            pw.print(mLastMemoryLevel);
16354                            pw.println(")");
16355                            break;
16356                    }
16357                    pw.print(" Free RAM: ");
16358                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16359                            + memInfo.getFreeSizeKb()));
16360                    pw.print(" (");
16361                    pw.print(stringifyKBSize(cachedPss));
16362                    pw.print(" cached pss + ");
16363                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16364                    pw.print(" cached kernel + ");
16365                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16366                    pw.println(" free)");
16367                } else {
16368                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16369                    pw.print(cachedPss + memInfo.getCachedSizeKb()
16370                            + memInfo.getFreeSizeKb()); pw.print(",");
16371                    pw.println(totalPss - cachedPss);
16372                }
16373            }
16374            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16375                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16376                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16377            if (!isCompact) {
16378                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16379                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16380                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16381                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16382                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16383            } else {
16384                pw.print("lostram,"); pw.println(lostRAM);
16385            }
16386            if (!brief) {
16387                if (memInfo.getZramTotalSizeKb() != 0) {
16388                    if (!isCompact) {
16389                        pw.print("     ZRAM: ");
16390                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16391                                pw.print(" physical used for ");
16392                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16393                                        - memInfo.getSwapFreeSizeKb()));
16394                                pw.print(" in swap (");
16395                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16396                                pw.println(" total swap)");
16397                    } else {
16398                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16399                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16400                                pw.println(memInfo.getSwapFreeSizeKb());
16401                    }
16402                }
16403                final long[] ksm = getKsmInfo();
16404                if (!isCompact) {
16405                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16406                            || ksm[KSM_VOLATILE] != 0) {
16407                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16408                                pw.print(" saved from shared ");
16409                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16410                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16411                                pw.print(" unshared; ");
16412                                pw.print(stringifyKBSize(
16413                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
16414                    }
16415                    pw.print("   Tuning: ");
16416                    pw.print(ActivityManager.staticGetMemoryClass());
16417                    pw.print(" (large ");
16418                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16419                    pw.print("), oom ");
16420                    pw.print(stringifySize(
16421                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16422                    pw.print(", restore limit ");
16423                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16424                    if (ActivityManager.isLowRamDeviceStatic()) {
16425                        pw.print(" (low-ram)");
16426                    }
16427                    if (ActivityManager.isHighEndGfx()) {
16428                        pw.print(" (high-end-gfx)");
16429                    }
16430                    pw.println();
16431                } else {
16432                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16433                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16434                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16435                    pw.print("tuning,");
16436                    pw.print(ActivityManager.staticGetMemoryClass());
16437                    pw.print(',');
16438                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16439                    pw.print(',');
16440                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16441                    if (ActivityManager.isLowRamDeviceStatic()) {
16442                        pw.print(",low-ram");
16443                    }
16444                    if (ActivityManager.isHighEndGfx()) {
16445                        pw.print(",high-end-gfx");
16446                    }
16447                    pw.println();
16448                }
16449            }
16450        }
16451    }
16452
16453    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16454            long memtrack, String name) {
16455        sb.append("  ");
16456        sb.append(ProcessList.makeOomAdjString(oomAdj));
16457        sb.append(' ');
16458        sb.append(ProcessList.makeProcStateString(procState));
16459        sb.append(' ');
16460        ProcessList.appendRamKb(sb, pss);
16461        sb.append(": ");
16462        sb.append(name);
16463        if (memtrack > 0) {
16464            sb.append(" (");
16465            sb.append(stringifyKBSize(memtrack));
16466            sb.append(" memtrack)");
16467        }
16468    }
16469
16470    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16471        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16472        sb.append(" (pid ");
16473        sb.append(mi.pid);
16474        sb.append(") ");
16475        sb.append(mi.adjType);
16476        sb.append('\n');
16477        if (mi.adjReason != null) {
16478            sb.append("                      ");
16479            sb.append(mi.adjReason);
16480            sb.append('\n');
16481        }
16482    }
16483
16484    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16485        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16486        for (int i=0, N=memInfos.size(); i<N; i++) {
16487            ProcessMemInfo mi = memInfos.get(i);
16488            infoMap.put(mi.pid, mi);
16489        }
16490        updateCpuStatsNow();
16491        long[] memtrackTmp = new long[1];
16492        final List<ProcessCpuTracker.Stats> stats;
16493        // Get a list of Stats that have vsize > 0
16494        synchronized (mProcessCpuTracker) {
16495            stats = mProcessCpuTracker.getStats((st) -> {
16496                return st.vsize > 0;
16497            });
16498        }
16499        final int statsCount = stats.size();
16500        for (int i = 0; i < statsCount; i++) {
16501            ProcessCpuTracker.Stats st = stats.get(i);
16502            long pss = Debug.getPss(st.pid, null, memtrackTmp);
16503            if (pss > 0) {
16504                if (infoMap.indexOfKey(st.pid) < 0) {
16505                    ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16506                            ProcessList.NATIVE_ADJ, -1, "native", null);
16507                    mi.pss = pss;
16508                    mi.memtrack = memtrackTmp[0];
16509                    memInfos.add(mi);
16510                }
16511            }
16512        }
16513
16514        long totalPss = 0;
16515        long totalMemtrack = 0;
16516        for (int i=0, N=memInfos.size(); i<N; i++) {
16517            ProcessMemInfo mi = memInfos.get(i);
16518            if (mi.pss == 0) {
16519                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16520                mi.memtrack = memtrackTmp[0];
16521            }
16522            totalPss += mi.pss;
16523            totalMemtrack += mi.memtrack;
16524        }
16525        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16526            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16527                if (lhs.oomAdj != rhs.oomAdj) {
16528                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16529                }
16530                if (lhs.pss != rhs.pss) {
16531                    return lhs.pss < rhs.pss ? 1 : -1;
16532                }
16533                return 0;
16534            }
16535        });
16536
16537        StringBuilder tag = new StringBuilder(128);
16538        StringBuilder stack = new StringBuilder(128);
16539        tag.append("Low on memory -- ");
16540        appendMemBucket(tag, totalPss, "total", false);
16541        appendMemBucket(stack, totalPss, "total", true);
16542
16543        StringBuilder fullNativeBuilder = new StringBuilder(1024);
16544        StringBuilder shortNativeBuilder = new StringBuilder(1024);
16545        StringBuilder fullJavaBuilder = new StringBuilder(1024);
16546
16547        boolean firstLine = true;
16548        int lastOomAdj = Integer.MIN_VALUE;
16549        long extraNativeRam = 0;
16550        long extraNativeMemtrack = 0;
16551        long cachedPss = 0;
16552        for (int i=0, N=memInfos.size(); i<N; i++) {
16553            ProcessMemInfo mi = memInfos.get(i);
16554
16555            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16556                cachedPss += mi.pss;
16557            }
16558
16559            if (mi.oomAdj != ProcessList.NATIVE_ADJ
16560                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
16561                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
16562                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16563                if (lastOomAdj != mi.oomAdj) {
16564                    lastOomAdj = mi.oomAdj;
16565                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16566                        tag.append(" / ");
16567                    }
16568                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16569                        if (firstLine) {
16570                            stack.append(":");
16571                            firstLine = false;
16572                        }
16573                        stack.append("\n\t at ");
16574                    } else {
16575                        stack.append("$");
16576                    }
16577                } else {
16578                    tag.append(" ");
16579                    stack.append("$");
16580                }
16581                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16582                    appendMemBucket(tag, mi.pss, mi.name, false);
16583                }
16584                appendMemBucket(stack, mi.pss, mi.name, true);
16585                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16586                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16587                    stack.append("(");
16588                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16589                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16590                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16591                            stack.append(":");
16592                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16593                        }
16594                    }
16595                    stack.append(")");
16596                }
16597            }
16598
16599            appendMemInfo(fullNativeBuilder, mi);
16600            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16601                // The short form only has native processes that are >= 512K.
16602                if (mi.pss >= 512) {
16603                    appendMemInfo(shortNativeBuilder, mi);
16604                } else {
16605                    extraNativeRam += mi.pss;
16606                    extraNativeMemtrack += mi.memtrack;
16607                }
16608            } else {
16609                // Short form has all other details, but if we have collected RAM
16610                // from smaller native processes let's dump a summary of that.
16611                if (extraNativeRam > 0) {
16612                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16613                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16614                    shortNativeBuilder.append('\n');
16615                    extraNativeRam = 0;
16616                }
16617                appendMemInfo(fullJavaBuilder, mi);
16618            }
16619        }
16620
16621        fullJavaBuilder.append("           ");
16622        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16623        fullJavaBuilder.append(": TOTAL");
16624        if (totalMemtrack > 0) {
16625            fullJavaBuilder.append(" (");
16626            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16627            fullJavaBuilder.append(" memtrack)");
16628        } else {
16629        }
16630        fullJavaBuilder.append("\n");
16631
16632        MemInfoReader memInfo = new MemInfoReader();
16633        memInfo.readMemInfo();
16634        final long[] infos = memInfo.getRawInfo();
16635
16636        StringBuilder memInfoBuilder = new StringBuilder(1024);
16637        Debug.getMemInfo(infos);
16638        memInfoBuilder.append("  MemInfo: ");
16639        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16640        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16641        memInfoBuilder.append(stringifyKBSize(
16642                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16643        memInfoBuilder.append(stringifyKBSize(
16644                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16645        memInfoBuilder.append(stringifyKBSize(
16646                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16647        memInfoBuilder.append("           ");
16648        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16649        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16650        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16651        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16652        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16653            memInfoBuilder.append("  ZRAM: ");
16654            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16655            memInfoBuilder.append(" RAM, ");
16656            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16657            memInfoBuilder.append(" swap total, ");
16658            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16659            memInfoBuilder.append(" swap free\n");
16660        }
16661        final long[] ksm = getKsmInfo();
16662        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16663                || ksm[KSM_VOLATILE] != 0) {
16664            memInfoBuilder.append("  KSM: ");
16665            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16666            memInfoBuilder.append(" saved from shared ");
16667            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16668            memInfoBuilder.append("\n       ");
16669            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16670            memInfoBuilder.append(" unshared; ");
16671            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16672            memInfoBuilder.append(" volatile\n");
16673        }
16674        memInfoBuilder.append("  Free RAM: ");
16675        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16676                + memInfo.getFreeSizeKb()));
16677        memInfoBuilder.append("\n");
16678        memInfoBuilder.append("  Used RAM: ");
16679        memInfoBuilder.append(stringifyKBSize(
16680                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16681        memInfoBuilder.append("\n");
16682        memInfoBuilder.append("  Lost RAM: ");
16683        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16684                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16685                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16686        memInfoBuilder.append("\n");
16687        Slog.i(TAG, "Low on memory:");
16688        Slog.i(TAG, shortNativeBuilder.toString());
16689        Slog.i(TAG, fullJavaBuilder.toString());
16690        Slog.i(TAG, memInfoBuilder.toString());
16691
16692        StringBuilder dropBuilder = new StringBuilder(1024);
16693        /*
16694        StringWriter oomSw = new StringWriter();
16695        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16696        StringWriter catSw = new StringWriter();
16697        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16698        String[] emptyArgs = new String[] { };
16699        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16700        oomPw.flush();
16701        String oomString = oomSw.toString();
16702        */
16703        dropBuilder.append("Low on memory:");
16704        dropBuilder.append(stack);
16705        dropBuilder.append('\n');
16706        dropBuilder.append(fullNativeBuilder);
16707        dropBuilder.append(fullJavaBuilder);
16708        dropBuilder.append('\n');
16709        dropBuilder.append(memInfoBuilder);
16710        dropBuilder.append('\n');
16711        /*
16712        dropBuilder.append(oomString);
16713        dropBuilder.append('\n');
16714        */
16715        StringWriter catSw = new StringWriter();
16716        synchronized (ActivityManagerService.this) {
16717            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16718            String[] emptyArgs = new String[] { };
16719            catPw.println();
16720            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16721            catPw.println();
16722            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16723                    false, null).dumpLocked();
16724            catPw.println();
16725            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16726            catPw.flush();
16727        }
16728        dropBuilder.append(catSw.toString());
16729        addErrorToDropBox("lowmem", null, "system_server", null,
16730                null, tag.toString(), dropBuilder.toString(), null, null);
16731        //Slog.i(TAG, "Sent to dropbox:");
16732        //Slog.i(TAG, dropBuilder.toString());
16733        synchronized (ActivityManagerService.this) {
16734            long now = SystemClock.uptimeMillis();
16735            if (mLastMemUsageReportTime < now) {
16736                mLastMemUsageReportTime = now;
16737            }
16738        }
16739    }
16740
16741    /**
16742     * Searches array of arguments for the specified string
16743     * @param args array of argument strings
16744     * @param value value to search for
16745     * @return true if the value is contained in the array
16746     */
16747    private static boolean scanArgs(String[] args, String value) {
16748        if (args != null) {
16749            for (String arg : args) {
16750                if (value.equals(arg)) {
16751                    return true;
16752                }
16753            }
16754        }
16755        return false;
16756    }
16757
16758    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16759            ContentProviderRecord cpr, boolean always) {
16760        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16761
16762        if (!inLaunching || always) {
16763            synchronized (cpr) {
16764                cpr.launchingApp = null;
16765                cpr.notifyAll();
16766            }
16767            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16768            String names[] = cpr.info.authority.split(";");
16769            for (int j = 0; j < names.length; j++) {
16770                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16771            }
16772        }
16773
16774        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16775            ContentProviderConnection conn = cpr.connections.get(i);
16776            if (conn.waiting) {
16777                // If this connection is waiting for the provider, then we don't
16778                // need to mess with its process unless we are always removing
16779                // or for some reason the provider is not currently launching.
16780                if (inLaunching && !always) {
16781                    continue;
16782                }
16783            }
16784            ProcessRecord capp = conn.client;
16785            conn.dead = true;
16786            if (conn.stableCount > 0) {
16787                if (!capp.persistent && capp.thread != null
16788                        && capp.pid != 0
16789                        && capp.pid != MY_PID) {
16790                    capp.kill("depends on provider "
16791                            + cpr.name.flattenToShortString()
16792                            + " in dying proc " + (proc != null ? proc.processName : "??")
16793                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
16794                }
16795            } else if (capp.thread != null && conn.provider.provider != null) {
16796                try {
16797                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16798                } catch (RemoteException e) {
16799                }
16800                // In the protocol here, we don't expect the client to correctly
16801                // clean up this connection, we'll just remove it.
16802                cpr.connections.remove(i);
16803                if (conn.client.conProviders.remove(conn)) {
16804                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16805                }
16806            }
16807        }
16808
16809        if (inLaunching && always) {
16810            mLaunchingProviders.remove(cpr);
16811        }
16812        return inLaunching;
16813    }
16814
16815    /**
16816     * Main code for cleaning up a process when it has gone away.  This is
16817     * called both as a result of the process dying, or directly when stopping
16818     * a process when running in single process mode.
16819     *
16820     * @return Returns true if the given process has been restarted, so the
16821     * app that was passed in must remain on the process lists.
16822     */
16823    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16824            boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
16825        Slog.d(TAG, "cleanUpApplicationRecord -- " + app.pid);
16826        if (index >= 0) {
16827            removeLruProcessLocked(app);
16828            ProcessList.remove(app.pid);
16829        }
16830
16831        mProcessesToGc.remove(app);
16832        mPendingPssProcesses.remove(app);
16833
16834        // Dismiss any open dialogs.
16835        if (app.crashDialog != null && !app.forceCrashReport) {
16836            app.crashDialog.dismiss();
16837            app.crashDialog = null;
16838        }
16839        if (app.anrDialog != null) {
16840            app.anrDialog.dismiss();
16841            app.anrDialog = null;
16842        }
16843        if (app.waitDialog != null) {
16844            app.waitDialog.dismiss();
16845            app.waitDialog = null;
16846        }
16847
16848        app.crashing = false;
16849        app.notResponding = false;
16850
16851        app.resetPackageList(mProcessStats);
16852        app.unlinkDeathRecipient();
16853        app.makeInactive(mProcessStats);
16854        app.waitingToKill = null;
16855        app.forcingToForeground = null;
16856        updateProcessForegroundLocked(app, false, false);
16857        app.foregroundActivities = false;
16858        app.hasShownUi = false;
16859        app.treatLikeActivity = false;
16860        app.hasAboveClient = false;
16861        app.hasClientActivities = false;
16862
16863        mServices.killServicesLocked(app, allowRestart);
16864
16865        boolean restart = false;
16866
16867        // Remove published content providers.
16868        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16869            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16870            final boolean always = app.bad || !allowRestart;
16871            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16872            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16873                // We left the provider in the launching list, need to
16874                // restart it.
16875                restart = true;
16876            }
16877
16878            cpr.provider = null;
16879            cpr.proc = null;
16880        }
16881        app.pubProviders.clear();
16882
16883        // Take care of any launching providers waiting for this process.
16884        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16885            restart = true;
16886        }
16887
16888        // Unregister from connected content providers.
16889        if (!app.conProviders.isEmpty()) {
16890            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16891                ContentProviderConnection conn = app.conProviders.get(i);
16892                conn.provider.connections.remove(conn);
16893                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16894                        conn.provider.name);
16895            }
16896            app.conProviders.clear();
16897        }
16898
16899        // At this point there may be remaining entries in mLaunchingProviders
16900        // where we were the only one waiting, so they are no longer of use.
16901        // Look for these and clean up if found.
16902        // XXX Commented out for now.  Trying to figure out a way to reproduce
16903        // the actual situation to identify what is actually going on.
16904        if (false) {
16905            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16906                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16907                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16908                    synchronized (cpr) {
16909                        cpr.launchingApp = null;
16910                        cpr.notifyAll();
16911                    }
16912                }
16913            }
16914        }
16915
16916        skipCurrentReceiverLocked(app);
16917
16918        // Unregister any receivers.
16919        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16920            removeReceiverLocked(app.receivers.valueAt(i));
16921        }
16922        app.receivers.clear();
16923
16924        // If the app is undergoing backup, tell the backup manager about it
16925        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16926            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16927                    + mBackupTarget.appInfo + " died during backup");
16928            try {
16929                IBackupManager bm = IBackupManager.Stub.asInterface(
16930                        ServiceManager.getService(Context.BACKUP_SERVICE));
16931                bm.agentDisconnected(app.info.packageName);
16932            } catch (RemoteException e) {
16933                // can't happen; backup manager is local
16934            }
16935        }
16936
16937        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16938            ProcessChangeItem item = mPendingProcessChanges.get(i);
16939            if (item.pid == app.pid) {
16940                mPendingProcessChanges.remove(i);
16941                mAvailProcessChanges.add(item);
16942            }
16943        }
16944        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16945                null).sendToTarget();
16946
16947        // If the caller is restarting this app, then leave it in its
16948        // current lists and let the caller take care of it.
16949        if (restarting) {
16950            return false;
16951        }
16952
16953        if (!app.persistent || app.isolated) {
16954            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16955                    "Removing non-persistent process during cleanup: " + app);
16956            if (!replacingPid) {
16957                removeProcessNameLocked(app.processName, app.uid);
16958            }
16959            if (mHeavyWeightProcess == app) {
16960                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16961                        mHeavyWeightProcess.userId, 0));
16962                mHeavyWeightProcess = null;
16963            }
16964        } else if (!app.removed) {
16965            // This app is persistent, so we need to keep its record around.
16966            // If it is not already on the pending app list, add it there
16967            // and start a new process for it.
16968            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16969                mPersistentStartingProcesses.add(app);
16970                restart = true;
16971            }
16972        }
16973        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16974                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16975        mProcessesOnHold.remove(app);
16976
16977        if (app == mHomeProcess) {
16978            mHomeProcess = null;
16979        }
16980        if (app == mPreviousProcess) {
16981            mPreviousProcess = null;
16982        }
16983
16984        if (restart && !app.isolated) {
16985            // We have components that still need to be running in the
16986            // process, so re-launch it.
16987            if (index < 0) {
16988                ProcessList.remove(app.pid);
16989            }
16990            addProcessNameLocked(app);
16991            startProcessLocked(app, "restart", app.processName);
16992            return true;
16993        } else if (app.pid > 0 && app.pid != MY_PID) {
16994            // Goodbye!
16995            boolean removed;
16996            synchronized (mPidsSelfLocked) {
16997                mPidsSelfLocked.remove(app.pid);
16998                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16999            }
17000            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
17001            if (app.isolated) {
17002                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
17003            }
17004            app.setPid(0);
17005        }
17006        return false;
17007    }
17008
17009    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
17010        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17011            ContentProviderRecord cpr = mLaunchingProviders.get(i);
17012            if (cpr.launchingApp == app) {
17013                return true;
17014            }
17015        }
17016        return false;
17017    }
17018
17019    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
17020        // Look through the content providers we are waiting to have launched,
17021        // and if any run in this process then either schedule a restart of
17022        // the process or kill the client waiting for it if this process has
17023        // gone bad.
17024        boolean restart = false;
17025        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17026            ContentProviderRecord cpr = mLaunchingProviders.get(i);
17027            if (cpr.launchingApp == app) {
17028                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
17029                    restart = true;
17030                } else {
17031                    removeDyingProviderLocked(app, cpr, true);
17032                }
17033            }
17034        }
17035        return restart;
17036    }
17037
17038    // =========================================================
17039    // SERVICES
17040    // =========================================================
17041
17042    @Override
17043    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
17044            int flags) {
17045        enforceNotIsolatedCaller("getServices");
17046        synchronized (this) {
17047            return mServices.getRunningServiceInfoLocked(maxNum, flags);
17048        }
17049    }
17050
17051    @Override
17052    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
17053        enforceNotIsolatedCaller("getRunningServiceControlPanel");
17054        synchronized (this) {
17055            return mServices.getRunningServiceControlPanelLocked(name);
17056        }
17057    }
17058
17059    @Override
17060    public ComponentName startService(IApplicationThread caller, Intent service,
17061            String resolvedType, String callingPackage, int userId)
17062            throws TransactionTooLargeException {
17063        enforceNotIsolatedCaller("startService");
17064        // Refuse possible leaked file descriptors
17065        if (service != null && service.hasFileDescriptors() == true) {
17066            throw new IllegalArgumentException("File descriptors passed in Intent");
17067        }
17068
17069        if (callingPackage == null) {
17070            throw new IllegalArgumentException("callingPackage cannot be null");
17071        }
17072
17073        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17074                "startService: " + service + " type=" + resolvedType);
17075        synchronized(this) {
17076            final int callingPid = Binder.getCallingPid();
17077            final int callingUid = Binder.getCallingUid();
17078            final long origId = Binder.clearCallingIdentity();
17079            ComponentName res = mServices.startServiceLocked(caller, service,
17080                    resolvedType, callingPid, callingUid, callingPackage, userId);
17081            Binder.restoreCallingIdentity(origId);
17082            return res;
17083        }
17084    }
17085
17086    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
17087            String callingPackage, int userId)
17088            throws TransactionTooLargeException {
17089        synchronized(this) {
17090            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17091                    "startServiceInPackage: " + service + " type=" + resolvedType);
17092            final long origId = Binder.clearCallingIdentity();
17093            ComponentName res = mServices.startServiceLocked(null, service,
17094                    resolvedType, -1, uid, callingPackage, userId);
17095            Binder.restoreCallingIdentity(origId);
17096            return res;
17097        }
17098    }
17099
17100    @Override
17101    public int stopService(IApplicationThread caller, Intent service,
17102            String resolvedType, int userId) {
17103        enforceNotIsolatedCaller("stopService");
17104        // Refuse possible leaked file descriptors
17105        if (service != null && service.hasFileDescriptors() == true) {
17106            throw new IllegalArgumentException("File descriptors passed in Intent");
17107        }
17108
17109        synchronized(this) {
17110            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
17111        }
17112    }
17113
17114    @Override
17115    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
17116        enforceNotIsolatedCaller("peekService");
17117        // Refuse possible leaked file descriptors
17118        if (service != null && service.hasFileDescriptors() == true) {
17119            throw new IllegalArgumentException("File descriptors passed in Intent");
17120        }
17121
17122        if (callingPackage == null) {
17123            throw new IllegalArgumentException("callingPackage cannot be null");
17124        }
17125
17126        synchronized(this) {
17127            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
17128        }
17129    }
17130
17131    @Override
17132    public boolean stopServiceToken(ComponentName className, IBinder token,
17133            int startId) {
17134        synchronized(this) {
17135            return mServices.stopServiceTokenLocked(className, token, startId);
17136        }
17137    }
17138
17139    @Override
17140    public void setServiceForeground(ComponentName className, IBinder token,
17141            int id, Notification notification, int flags) {
17142        synchronized(this) {
17143            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
17144        }
17145    }
17146
17147    @Override
17148    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
17149            boolean requireFull, String name, String callerPackage) {
17150        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
17151                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
17152    }
17153
17154    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
17155            String className, int flags) {
17156        boolean result = false;
17157        // For apps that don't have pre-defined UIDs, check for permission
17158        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
17159            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17160                if (ActivityManager.checkUidPermission(
17161                        INTERACT_ACROSS_USERS,
17162                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
17163                    ComponentName comp = new ComponentName(aInfo.packageName, className);
17164                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
17165                            + " requests FLAG_SINGLE_USER, but app does not hold "
17166                            + INTERACT_ACROSS_USERS;
17167                    Slog.w(TAG, msg);
17168                    throw new SecurityException(msg);
17169                }
17170                // Permission passed
17171                result = true;
17172            }
17173        } else if ("system".equals(componentProcessName)) {
17174            result = true;
17175        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17176            // Phone app and persistent apps are allowed to export singleuser providers.
17177            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
17178                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
17179        }
17180        if (DEBUG_MU) Slog.v(TAG_MU,
17181                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
17182                + Integer.toHexString(flags) + ") = " + result);
17183        return result;
17184    }
17185
17186    /**
17187     * Checks to see if the caller is in the same app as the singleton
17188     * component, or the component is in a special app. It allows special apps
17189     * to export singleton components but prevents exporting singleton
17190     * components for regular apps.
17191     */
17192    boolean isValidSingletonCall(int callingUid, int componentUid) {
17193        int componentAppId = UserHandle.getAppId(componentUid);
17194        return UserHandle.isSameApp(callingUid, componentUid)
17195                || componentAppId == Process.SYSTEM_UID
17196                || componentAppId == Process.PHONE_UID
17197                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
17198                        == PackageManager.PERMISSION_GRANTED;
17199    }
17200
17201    public int bindService(IApplicationThread caller, IBinder token, Intent service,
17202            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
17203            int userId) throws TransactionTooLargeException {
17204        enforceNotIsolatedCaller("bindService");
17205
17206        // Refuse possible leaked file descriptors
17207        if (service != null && service.hasFileDescriptors() == true) {
17208            throw new IllegalArgumentException("File descriptors passed in Intent");
17209        }
17210
17211        if (callingPackage == null) {
17212            throw new IllegalArgumentException("callingPackage cannot be null");
17213        }
17214
17215        synchronized(this) {
17216            return mServices.bindServiceLocked(caller, token, service,
17217                    resolvedType, connection, flags, callingPackage, userId);
17218        }
17219    }
17220
17221    public boolean unbindService(IServiceConnection connection) {
17222        synchronized (this) {
17223            return mServices.unbindServiceLocked(connection);
17224        }
17225    }
17226
17227    public void publishService(IBinder token, Intent intent, IBinder service) {
17228        // Refuse possible leaked file descriptors
17229        if (intent != null && intent.hasFileDescriptors() == true) {
17230            throw new IllegalArgumentException("File descriptors passed in Intent");
17231        }
17232
17233        synchronized(this) {
17234            if (!(token instanceof ServiceRecord)) {
17235                throw new IllegalArgumentException("Invalid service token");
17236            }
17237            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17238        }
17239    }
17240
17241    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17242        // Refuse possible leaked file descriptors
17243        if (intent != null && intent.hasFileDescriptors() == true) {
17244            throw new IllegalArgumentException("File descriptors passed in Intent");
17245        }
17246
17247        synchronized(this) {
17248            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17249        }
17250    }
17251
17252    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17253        synchronized(this) {
17254            if (!(token instanceof ServiceRecord)) {
17255                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17256                throw new IllegalArgumentException("Invalid service token");
17257            }
17258            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17259        }
17260    }
17261
17262    // =========================================================
17263    // BACKUP AND RESTORE
17264    // =========================================================
17265
17266    // Cause the target app to be launched if necessary and its backup agent
17267    // instantiated.  The backup agent will invoke backupAgentCreated() on the
17268    // activity manager to announce its creation.
17269    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
17270        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
17271        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17272
17273        IPackageManager pm = AppGlobals.getPackageManager();
17274        ApplicationInfo app = null;
17275        try {
17276            app = pm.getApplicationInfo(packageName, 0, userId);
17277        } catch (RemoteException e) {
17278            // can't happen; package manager is process-local
17279        }
17280        if (app == null) {
17281            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
17282            return false;
17283        }
17284
17285        synchronized(this) {
17286            // !!! TODO: currently no check here that we're already bound
17287            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17288            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17289            synchronized (stats) {
17290                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17291            }
17292
17293            // Backup agent is now in use, its package can't be stopped.
17294            try {
17295                AppGlobals.getPackageManager().setPackageStoppedState(
17296                        app.packageName, false, UserHandle.getUserId(app.uid));
17297            } catch (RemoteException e) {
17298            } catch (IllegalArgumentException e) {
17299                Slog.w(TAG, "Failed trying to unstop package "
17300                        + app.packageName + ": " + e);
17301            }
17302
17303            BackupRecord r = new BackupRecord(ss, app, backupMode);
17304            ComponentName hostingName =
17305                    (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
17306                            ? new ComponentName(app.packageName, app.backupAgentName)
17307                            : new ComponentName("android", "FullBackupAgent");
17308            // startProcessLocked() returns existing proc's record if it's already running
17309            ProcessRecord proc = startProcessLocked(app.processName, app,
17310                    false, 0, "backup", hostingName, false, false, false);
17311            if (proc == null) {
17312                Slog.e(TAG, "Unable to start backup agent process " + r);
17313                return false;
17314            }
17315
17316            // If the app is a regular app (uid >= 10000) and not the system server or phone
17317            // process, etc, then mark it as being in full backup so that certain calls to the
17318            // process can be blocked. This is not reset to false anywhere because we kill the
17319            // process after the full backup is done and the ProcessRecord will vaporize anyway.
17320            if (UserHandle.isApp(app.uid) &&
17321                    backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
17322                proc.inFullBackup = true;
17323            }
17324            r.app = proc;
17325            mBackupTarget = r;
17326            mBackupAppName = app.packageName;
17327
17328            // Try not to kill the process during backup
17329            updateOomAdjLocked(proc);
17330
17331            // If the process is already attached, schedule the creation of the backup agent now.
17332            // If it is not yet live, this will be done when it attaches to the framework.
17333            if (proc.thread != null) {
17334                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17335                try {
17336                    proc.thread.scheduleCreateBackupAgent(app,
17337                            compatibilityInfoForPackageLocked(app), backupMode);
17338                } catch (RemoteException e) {
17339                    // Will time out on the backup manager side
17340                }
17341            } else {
17342                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17343            }
17344            // Invariants: at this point, the target app process exists and the application
17345            // is either already running or in the process of coming up.  mBackupTarget and
17346            // mBackupAppName describe the app, so that when it binds back to the AM we
17347            // know that it's scheduled for a backup-agent operation.
17348        }
17349
17350        return true;
17351    }
17352
17353    @Override
17354    public void clearPendingBackup() {
17355        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17356        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17357
17358        synchronized (this) {
17359            mBackupTarget = null;
17360            mBackupAppName = null;
17361        }
17362    }
17363
17364    // A backup agent has just come up
17365    public void backupAgentCreated(String agentPackageName, IBinder agent) {
17366        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17367                + " = " + agent);
17368
17369        synchronized(this) {
17370            if (!agentPackageName.equals(mBackupAppName)) {
17371                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17372                return;
17373            }
17374        }
17375
17376        long oldIdent = Binder.clearCallingIdentity();
17377        try {
17378            IBackupManager bm = IBackupManager.Stub.asInterface(
17379                    ServiceManager.getService(Context.BACKUP_SERVICE));
17380            bm.agentConnected(agentPackageName, agent);
17381        } catch (RemoteException e) {
17382            // can't happen; the backup manager service is local
17383        } catch (Exception e) {
17384            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17385            e.printStackTrace();
17386        } finally {
17387            Binder.restoreCallingIdentity(oldIdent);
17388        }
17389    }
17390
17391    // done with this agent
17392    public void unbindBackupAgent(ApplicationInfo appInfo) {
17393        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17394        if (appInfo == null) {
17395            Slog.w(TAG, "unbind backup agent for null app");
17396            return;
17397        }
17398
17399        synchronized(this) {
17400            try {
17401                if (mBackupAppName == null) {
17402                    Slog.w(TAG, "Unbinding backup agent with no active backup");
17403                    return;
17404                }
17405
17406                if (!mBackupAppName.equals(appInfo.packageName)) {
17407                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17408                    return;
17409                }
17410
17411                // Not backing this app up any more; reset its OOM adjustment
17412                final ProcessRecord proc = mBackupTarget.app;
17413                updateOomAdjLocked(proc);
17414
17415                // If the app crashed during backup, 'thread' will be null here
17416                if (proc.thread != null) {
17417                    try {
17418                        proc.thread.scheduleDestroyBackupAgent(appInfo,
17419                                compatibilityInfoForPackageLocked(appInfo));
17420                    } catch (Exception e) {
17421                        Slog.e(TAG, "Exception when unbinding backup agent:");
17422                        e.printStackTrace();
17423                    }
17424                }
17425            } finally {
17426                mBackupTarget = null;
17427                mBackupAppName = null;
17428            }
17429        }
17430    }
17431    // =========================================================
17432    // BROADCASTS
17433    // =========================================================
17434
17435    boolean isPendingBroadcastProcessLocked(int pid) {
17436        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17437                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17438    }
17439
17440    void skipPendingBroadcastLocked(int pid) {
17441            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17442            for (BroadcastQueue queue : mBroadcastQueues) {
17443                queue.skipPendingBroadcastLocked(pid);
17444            }
17445    }
17446
17447    // The app just attached; send any pending broadcasts that it should receive
17448    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17449        boolean didSomething = false;
17450        for (BroadcastQueue queue : mBroadcastQueues) {
17451            didSomething |= queue.sendPendingBroadcastsLocked(app);
17452        }
17453        return didSomething;
17454    }
17455
17456    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17457            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17458        enforceNotIsolatedCaller("registerReceiver");
17459        ArrayList<Intent> stickyIntents = null;
17460        ProcessRecord callerApp = null;
17461        int callingUid;
17462        int callingPid;
17463        synchronized(this) {
17464            if (caller != null) {
17465                callerApp = getRecordForAppLocked(caller);
17466                if (callerApp == null) {
17467                    throw new SecurityException(
17468                            "Unable to find app for caller " + caller
17469                            + " (pid=" + Binder.getCallingPid()
17470                            + ") when registering receiver " + receiver);
17471                }
17472                if (callerApp.info.uid != Process.SYSTEM_UID &&
17473                        !callerApp.pkgList.containsKey(callerPackage) &&
17474                        !"android".equals(callerPackage)) {
17475                    throw new SecurityException("Given caller package " + callerPackage
17476                            + " is not running in process " + callerApp);
17477                }
17478                callingUid = callerApp.info.uid;
17479                callingPid = callerApp.pid;
17480            } else {
17481                callerPackage = null;
17482                callingUid = Binder.getCallingUid();
17483                callingPid = Binder.getCallingPid();
17484            }
17485
17486            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17487                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17488
17489            Iterator<String> actions = filter.actionsIterator();
17490            if (actions == null) {
17491                ArrayList<String> noAction = new ArrayList<String>(1);
17492                noAction.add(null);
17493                actions = noAction.iterator();
17494            }
17495
17496            // Collect stickies of users
17497            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17498            while (actions.hasNext()) {
17499                String action = actions.next();
17500                for (int id : userIds) {
17501                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17502                    if (stickies != null) {
17503                        ArrayList<Intent> intents = stickies.get(action);
17504                        if (intents != null) {
17505                            if (stickyIntents == null) {
17506                                stickyIntents = new ArrayList<Intent>();
17507                            }
17508                            stickyIntents.addAll(intents);
17509                        }
17510                    }
17511                }
17512            }
17513        }
17514
17515        ArrayList<Intent> allSticky = null;
17516        if (stickyIntents != null) {
17517            final ContentResolver resolver = mContext.getContentResolver();
17518            // Look for any matching sticky broadcasts...
17519            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17520                Intent intent = stickyIntents.get(i);
17521                // If intent has scheme "content", it will need to acccess
17522                // provider that needs to lock mProviderMap in ActivityThread
17523                // and also it may need to wait application response, so we
17524                // cannot lock ActivityManagerService here.
17525                if (filter.match(resolver, intent, true, TAG) >= 0) {
17526                    if (allSticky == null) {
17527                        allSticky = new ArrayList<Intent>();
17528                    }
17529                    allSticky.add(intent);
17530                }
17531            }
17532        }
17533
17534        // The first sticky in the list is returned directly back to the client.
17535        Intent sticky = allSticky != null ? allSticky.get(0) : null;
17536        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17537        if (receiver == null) {
17538            return sticky;
17539        }
17540
17541        synchronized (this) {
17542            if (callerApp != null && (callerApp.thread == null
17543                    || callerApp.thread.asBinder() != caller.asBinder())) {
17544                // Original caller already died
17545                return null;
17546            }
17547            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17548            if (rl == null) {
17549                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17550                        userId, receiver);
17551                if (rl.app != null) {
17552                    rl.app.receivers.add(rl);
17553                } else {
17554                    try {
17555                        receiver.asBinder().linkToDeath(rl, 0);
17556                    } catch (RemoteException e) {
17557                        return sticky;
17558                    }
17559                    rl.linkedToDeath = true;
17560                }
17561                mRegisteredReceivers.put(receiver.asBinder(), rl);
17562            } else if (rl.uid != callingUid) {
17563                throw new IllegalArgumentException(
17564                        "Receiver requested to register for uid " + callingUid
17565                        + " was previously registered for uid " + rl.uid);
17566            } else if (rl.pid != callingPid) {
17567                throw new IllegalArgumentException(
17568                        "Receiver requested to register for pid " + callingPid
17569                        + " was previously registered for pid " + rl.pid);
17570            } else if (rl.userId != userId) {
17571                throw new IllegalArgumentException(
17572                        "Receiver requested to register for user " + userId
17573                        + " was previously registered for user " + rl.userId);
17574            }
17575            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17576                    permission, callingUid, userId);
17577            rl.add(bf);
17578            if (!bf.debugCheck()) {
17579                Slog.w(TAG, "==> For Dynamic broadcast");
17580            }
17581            mReceiverResolver.addFilter(bf);
17582
17583            // Enqueue broadcasts for all existing stickies that match
17584            // this filter.
17585            if (allSticky != null) {
17586                ArrayList receivers = new ArrayList();
17587                receivers.add(bf);
17588
17589                final int stickyCount = allSticky.size();
17590                for (int i = 0; i < stickyCount; i++) {
17591                    Intent intent = allSticky.get(i);
17592                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17593                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17594                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17595                            null, 0, null, null, false, true, true, -1);
17596                    queue.enqueueParallelBroadcastLocked(r);
17597                    queue.scheduleBroadcastsLocked();
17598                }
17599            }
17600
17601            return sticky;
17602        }
17603    }
17604
17605    public void unregisterReceiver(IIntentReceiver receiver) {
17606        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17607
17608        final long origId = Binder.clearCallingIdentity();
17609        try {
17610            boolean doTrim = false;
17611
17612            synchronized(this) {
17613                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17614                if (rl != null) {
17615                    final BroadcastRecord r = rl.curBroadcast;
17616                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17617                        final boolean doNext = r.queue.finishReceiverLocked(
17618                                r, r.resultCode, r.resultData, r.resultExtras,
17619                                r.resultAbort, false);
17620                        if (doNext) {
17621                            doTrim = true;
17622                            r.queue.processNextBroadcast(false);
17623                        }
17624                    }
17625
17626                    if (rl.app != null) {
17627                        rl.app.receivers.remove(rl);
17628                    }
17629                    removeReceiverLocked(rl);
17630                    if (rl.linkedToDeath) {
17631                        rl.linkedToDeath = false;
17632                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17633                    }
17634                }
17635            }
17636
17637            // If we actually concluded any broadcasts, we might now be able
17638            // to trim the recipients' apps from our working set
17639            if (doTrim) {
17640                trimApplications();
17641                return;
17642            }
17643
17644        } finally {
17645            Binder.restoreCallingIdentity(origId);
17646        }
17647    }
17648
17649    void removeReceiverLocked(ReceiverList rl) {
17650        mRegisteredReceivers.remove(rl.receiver.asBinder());
17651        for (int i = rl.size() - 1; i >= 0; i--) {
17652            mReceiverResolver.removeFilter(rl.get(i));
17653        }
17654    }
17655
17656    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17657        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17658            ProcessRecord r = mLruProcesses.get(i);
17659            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17660                try {
17661                    r.thread.dispatchPackageBroadcast(cmd, packages);
17662                } catch (RemoteException ex) {
17663                }
17664            }
17665        }
17666    }
17667
17668    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17669            int callingUid, int[] users) {
17670        // TODO: come back and remove this assumption to triage all broadcasts
17671        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17672
17673        List<ResolveInfo> receivers = null;
17674        try {
17675            HashSet<ComponentName> singleUserReceivers = null;
17676            boolean scannedFirstReceivers = false;
17677            for (int user : users) {
17678                // Skip users that have Shell restrictions, with exception of always permitted
17679                // Shell broadcasts
17680                if (callingUid == Process.SHELL_UID
17681                        && mUserController.hasUserRestriction(
17682                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17683                        && !isPermittedShellBroadcast(intent)) {
17684                    continue;
17685                }
17686                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17687                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17688                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17689                    // If this is not the system user, we need to check for
17690                    // any receivers that should be filtered out.
17691                    for (int i=0; i<newReceivers.size(); i++) {
17692                        ResolveInfo ri = newReceivers.get(i);
17693                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17694                            newReceivers.remove(i);
17695                            i--;
17696                        }
17697                    }
17698                }
17699                if (newReceivers != null && newReceivers.size() == 0) {
17700                    newReceivers = null;
17701                }
17702                if (receivers == null) {
17703                    receivers = newReceivers;
17704                } else if (newReceivers != null) {
17705                    // We need to concatenate the additional receivers
17706                    // found with what we have do far.  This would be easy,
17707                    // but we also need to de-dup any receivers that are
17708                    // singleUser.
17709                    if (!scannedFirstReceivers) {
17710                        // Collect any single user receivers we had already retrieved.
17711                        scannedFirstReceivers = true;
17712                        for (int i=0; i<receivers.size(); i++) {
17713                            ResolveInfo ri = receivers.get(i);
17714                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17715                                ComponentName cn = new ComponentName(
17716                                        ri.activityInfo.packageName, ri.activityInfo.name);
17717                                if (singleUserReceivers == null) {
17718                                    singleUserReceivers = new HashSet<ComponentName>();
17719                                }
17720                                singleUserReceivers.add(cn);
17721                            }
17722                        }
17723                    }
17724                    // Add the new results to the existing results, tracking
17725                    // and de-dupping single user receivers.
17726                    for (int i=0; i<newReceivers.size(); i++) {
17727                        ResolveInfo ri = newReceivers.get(i);
17728                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17729                            ComponentName cn = new ComponentName(
17730                                    ri.activityInfo.packageName, ri.activityInfo.name);
17731                            if (singleUserReceivers == null) {
17732                                singleUserReceivers = new HashSet<ComponentName>();
17733                            }
17734                            if (!singleUserReceivers.contains(cn)) {
17735                                singleUserReceivers.add(cn);
17736                                receivers.add(ri);
17737                            }
17738                        } else {
17739                            receivers.add(ri);
17740                        }
17741                    }
17742                }
17743            }
17744        } catch (RemoteException ex) {
17745            // pm is in same process, this will never happen.
17746        }
17747        return receivers;
17748    }
17749
17750    private boolean isPermittedShellBroadcast(Intent intent) {
17751        // remote bugreport should always be allowed to be taken
17752        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17753    }
17754
17755    private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
17756            String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
17757        final String action = intent.getAction();
17758        if (isProtectedBroadcast
17759                || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17760                || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17761                || Intent.ACTION_MEDIA_BUTTON.equals(action)
17762                || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17763                || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17764                || Intent.ACTION_MASTER_CLEAR.equals(action)
17765                || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17766                || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17767                || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17768                || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17769                || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17770            // Broadcast is either protected, or it's a public action that
17771            // we've relaxed, so it's fine for system internals to send.
17772            return;
17773        }
17774
17775        // This broadcast may be a problem...  but there are often system components that
17776        // want to send an internal broadcast to themselves, which is annoying to have to
17777        // explicitly list each action as a protected broadcast, so we will check for that
17778        // one safe case and allow it: an explicit broadcast, only being received by something
17779        // that has protected itself.
17780        if (receivers != null && receivers.size() > 0
17781                && (intent.getPackage() != null || intent.getComponent() != null)) {
17782            boolean allProtected = true;
17783            for (int i = receivers.size()-1; i >= 0; i--) {
17784                Object target = receivers.get(i);
17785                if (target instanceof ResolveInfo) {
17786                    ResolveInfo ri = (ResolveInfo)target;
17787                    if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
17788                        allProtected = false;
17789                        break;
17790                    }
17791                } else {
17792                    BroadcastFilter bf = (BroadcastFilter)target;
17793                    if (bf.requiredPermission == null) {
17794                        allProtected = false;
17795                        break;
17796                    }
17797                }
17798            }
17799            if (allProtected) {
17800                // All safe!
17801                return;
17802            }
17803        }
17804
17805        // The vast majority of broadcasts sent from system internals
17806        // should be protected to avoid security holes, so yell loudly
17807        // to ensure we examine these cases.
17808        if (callerApp != null) {
17809            Log.wtf(TAG, "Sending non-protected broadcast " + action
17810                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17811                    new Throwable());
17812        } else {
17813            Log.wtf(TAG, "Sending non-protected broadcast " + action
17814                            + " from system uid " + UserHandle.formatUid(callingUid)
17815                            + " pkg " + callerPackage,
17816                    new Throwable());
17817        }
17818    }
17819
17820    final int broadcastIntentLocked(ProcessRecord callerApp,
17821            String callerPackage, Intent intent, String resolvedType,
17822            IIntentReceiver resultTo, int resultCode, String resultData,
17823            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17824            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17825        intent = new Intent(intent);
17826
17827        // By default broadcasts do not go to stopped apps.
17828        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17829
17830        // If we have not finished booting, don't allow this to launch new processes.
17831        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17832            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17833        }
17834
17835        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17836                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17837                + " ordered=" + ordered + " userid=" + userId);
17838        if ((resultTo != null) && !ordered) {
17839            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17840        }
17841
17842        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17843                ALLOW_NON_FULL, "broadcast", callerPackage);
17844
17845        // Make sure that the user who is receiving this broadcast is running.
17846        // If not, we will just skip it. Make an exception for shutdown broadcasts
17847        // and upgrade steps.
17848
17849        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17850            if ((callingUid != Process.SYSTEM_UID
17851                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17852                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17853                Slog.w(TAG, "Skipping broadcast of " + intent
17854                        + ": user " + userId + " is stopped");
17855                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17856            }
17857        }
17858
17859        BroadcastOptions brOptions = null;
17860        if (bOptions != null) {
17861            brOptions = new BroadcastOptions(bOptions);
17862            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17863                // See if the caller is allowed to do this.  Note we are checking against
17864                // the actual real caller (not whoever provided the operation as say a
17865                // PendingIntent), because that who is actually supplied the arguments.
17866                if (checkComponentPermission(
17867                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17868                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17869                        != PackageManager.PERMISSION_GRANTED) {
17870                    String msg = "Permission Denial: " + intent.getAction()
17871                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17872                            + ", uid=" + callingUid + ")"
17873                            + " requires "
17874                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17875                    Slog.w(TAG, msg);
17876                    throw new SecurityException(msg);
17877                }
17878            }
17879        }
17880
17881        // Verify that protected broadcasts are only being sent by system code,
17882        // and that system code is only sending protected broadcasts.
17883        final String action = intent.getAction();
17884        final boolean isProtectedBroadcast;
17885        try {
17886            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17887        } catch (RemoteException e) {
17888            Slog.w(TAG, "Remote exception", e);
17889            return ActivityManager.BROADCAST_SUCCESS;
17890        }
17891
17892        final boolean isCallerSystem;
17893        switch (UserHandle.getAppId(callingUid)) {
17894            case Process.ROOT_UID:
17895            case Process.SYSTEM_UID:
17896            case Process.PHONE_UID:
17897            case Process.BLUETOOTH_UID:
17898            case Process.NFC_UID:
17899                isCallerSystem = true;
17900                break;
17901            default:
17902                isCallerSystem = (callerApp != null) && callerApp.persistent;
17903                break;
17904        }
17905
17906        // First line security check before anything else: stop non-system apps from
17907        // sending protected broadcasts.
17908        if (!isCallerSystem) {
17909            if (isProtectedBroadcast) {
17910                String msg = "Permission Denial: not allowed to send broadcast "
17911                        + action + " from pid="
17912                        + callingPid + ", uid=" + callingUid;
17913                Slog.w(TAG, msg);
17914                throw new SecurityException(msg);
17915
17916            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17917                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17918                // Special case for compatibility: we don't want apps to send this,
17919                // but historically it has not been protected and apps may be using it
17920                // to poke their own app widget.  So, instead of making it protected,
17921                // just limit it to the caller.
17922                if (callerPackage == null) {
17923                    String msg = "Permission Denial: not allowed to send broadcast "
17924                            + action + " from unknown caller.";
17925                    Slog.w(TAG, msg);
17926                    throw new SecurityException(msg);
17927                } else if (intent.getComponent() != null) {
17928                    // They are good enough to send to an explicit component...  verify
17929                    // it is being sent to the calling app.
17930                    if (!intent.getComponent().getPackageName().equals(
17931                            callerPackage)) {
17932                        String msg = "Permission Denial: not allowed to send broadcast "
17933                                + action + " to "
17934                                + intent.getComponent().getPackageName() + " from "
17935                                + callerPackage;
17936                        Slog.w(TAG, msg);
17937                        throw new SecurityException(msg);
17938                    }
17939                } else {
17940                    // Limit broadcast to their own package.
17941                    intent.setPackage(callerPackage);
17942                }
17943            }
17944        }
17945
17946        if (action != null) {
17947            switch (action) {
17948                case Intent.ACTION_UID_REMOVED:
17949                case Intent.ACTION_PACKAGE_REMOVED:
17950                case Intent.ACTION_PACKAGE_CHANGED:
17951                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17952                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17953                case Intent.ACTION_PACKAGES_SUSPENDED:
17954                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17955                    // Handle special intents: if this broadcast is from the package
17956                    // manager about a package being removed, we need to remove all of
17957                    // its activities from the history stack.
17958                    if (checkComponentPermission(
17959                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17960                            callingPid, callingUid, -1, true)
17961                            != PackageManager.PERMISSION_GRANTED) {
17962                        String msg = "Permission Denial: " + intent.getAction()
17963                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17964                                + ", uid=" + callingUid + ")"
17965                                + " requires "
17966                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17967                        Slog.w(TAG, msg);
17968                        throw new SecurityException(msg);
17969                    }
17970                    switch (action) {
17971                        case Intent.ACTION_UID_REMOVED:
17972                            final Bundle intentExtras = intent.getExtras();
17973                            final int uid = intentExtras != null
17974                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17975                            if (uid >= 0) {
17976                                mBatteryStatsService.removeUid(uid);
17977                                mAppOpsService.uidRemoved(uid);
17978                            }
17979                            break;
17980                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17981                            // If resources are unavailable just force stop all those packages
17982                            // and flush the attribute cache as well.
17983                            String list[] =
17984                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17985                            if (list != null && list.length > 0) {
17986                                for (int i = 0; i < list.length; i++) {
17987                                    forceStopPackageLocked(list[i], -1, false, true, true,
17988                                            false, false, userId, "storage unmount");
17989                                }
17990                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17991                                sendPackageBroadcastLocked(
17992                                        ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
17993                                        list, userId);
17994                            }
17995                            break;
17996                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17997                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17998                            break;
17999                        case Intent.ACTION_PACKAGE_REMOVED:
18000                        case Intent.ACTION_PACKAGE_CHANGED:
18001                            Uri data = intent.getData();
18002                            String ssp;
18003                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
18004                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
18005                                final boolean replacing =
18006                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18007                                final boolean killProcess =
18008                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
18009                                final boolean fullUninstall = removed && !replacing;
18010                                if (removed) {
18011                                    if (killProcess) {
18012                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
18013                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
18014                                                false, true, true, false, fullUninstall, userId,
18015                                                removed ? "pkg removed" : "pkg changed");
18016                                    }
18017                                    final int cmd = killProcess
18018                                            ? ApplicationThreadConstants.PACKAGE_REMOVED
18019                                            : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
18020                                    sendPackageBroadcastLocked(cmd,
18021                                            new String[] {ssp}, userId);
18022                                    if (fullUninstall) {
18023                                        mAppOpsService.packageRemoved(
18024                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
18025
18026                                        // Remove all permissions granted from/to this package
18027                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
18028
18029                                        removeTasksByPackageNameLocked(ssp, userId);
18030
18031                                        // Hide the "unsupported display" dialog if necessary.
18032                                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18033                                                mUnsupportedDisplaySizeDialog.getPackageName())) {
18034                                            mUnsupportedDisplaySizeDialog.dismiss();
18035                                            mUnsupportedDisplaySizeDialog = null;
18036                                        }
18037                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
18038                                        mBatteryStatsService.notePackageUninstalled(ssp);
18039                                    }
18040                                } else {
18041                                    if (killProcess) {
18042                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
18043                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
18044                                                userId, ProcessList.INVALID_ADJ,
18045                                                false, true, true, false, "change " + ssp);
18046                                    }
18047                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
18048                                            intent.getStringArrayExtra(
18049                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
18050                                }
18051                            }
18052                            break;
18053                        case Intent.ACTION_PACKAGES_SUSPENDED:
18054                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
18055                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
18056                                    intent.getAction());
18057                            final String[] packageNames = intent.getStringArrayExtra(
18058                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
18059                            final int userHandle = intent.getIntExtra(
18060                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
18061
18062                            synchronized(ActivityManagerService.this) {
18063                                mRecentTasks.onPackagesSuspendedChanged(
18064                                        packageNames, suspended, userHandle);
18065                            }
18066                            break;
18067                    }
18068                    break;
18069                case Intent.ACTION_PACKAGE_REPLACED:
18070                {
18071                    final Uri data = intent.getData();
18072                    final String ssp;
18073                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18074                        final ApplicationInfo aInfo =
18075                                getPackageManagerInternalLocked().getApplicationInfo(
18076                                        ssp,
18077                                        userId);
18078                        if (aInfo == null) {
18079                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
18080                                    + " ssp=" + ssp + " data=" + data);
18081                            return ActivityManager.BROADCAST_SUCCESS;
18082                        }
18083                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
18084                        sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
18085                                new String[] {ssp}, userId);
18086                    }
18087                    break;
18088                }
18089                case Intent.ACTION_PACKAGE_ADDED:
18090                {
18091                    // Special case for adding a package: by default turn on compatibility mode.
18092                    Uri data = intent.getData();
18093                    String ssp;
18094                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18095                        final boolean replacing =
18096                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18097                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
18098
18099                        try {
18100                            ApplicationInfo ai = AppGlobals.getPackageManager().
18101                                    getApplicationInfo(ssp, 0, 0);
18102                            mBatteryStatsService.notePackageInstalled(ssp,
18103                                    ai != null ? ai.versionCode : 0);
18104                        } catch (RemoteException e) {
18105                        }
18106                    }
18107                    break;
18108                }
18109                case Intent.ACTION_PACKAGE_DATA_CLEARED:
18110                {
18111                    Uri data = intent.getData();
18112                    String ssp;
18113                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18114                        // Hide the "unsupported display" dialog if necessary.
18115                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18116                                mUnsupportedDisplaySizeDialog.getPackageName())) {
18117                            mUnsupportedDisplaySizeDialog.dismiss();
18118                            mUnsupportedDisplaySizeDialog = null;
18119                        }
18120                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
18121                    }
18122                    break;
18123                }
18124                case Intent.ACTION_TIMEZONE_CHANGED:
18125                    // If this is the time zone changed action, queue up a message that will reset
18126                    // the timezone of all currently running processes. This message will get
18127                    // queued up before the broadcast happens.
18128                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
18129                    break;
18130                case Intent.ACTION_TIME_CHANGED:
18131                    // If the user set the time, let all running processes know.
18132                    final int is24Hour =
18133                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
18134                                    : 0;
18135                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
18136                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18137                    synchronized (stats) {
18138                        stats.noteCurrentTimeChangedLocked();
18139                    }
18140                    break;
18141                case Intent.ACTION_CLEAR_DNS_CACHE:
18142                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
18143                    break;
18144                case Proxy.PROXY_CHANGE_ACTION:
18145                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
18146                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
18147                    break;
18148                case android.hardware.Camera.ACTION_NEW_PICTURE:
18149                case android.hardware.Camera.ACTION_NEW_VIDEO:
18150                    // These broadcasts are no longer allowed by the system, since they can
18151                    // cause significant thrashing at a crictical point (using the camera).
18152                    // Apps should use JobScehduler to monitor for media provider changes.
18153                    Slog.w(TAG, action + " no longer allowed; dropping from "
18154                            + UserHandle.formatUid(callingUid));
18155                    if (resultTo != null) {
18156                        final BroadcastQueue queue = broadcastQueueForIntent(intent);
18157                        try {
18158                            queue.performReceiveLocked(callerApp, resultTo, intent,
18159                                    Activity.RESULT_CANCELED, null, null,
18160                                    false, false, userId);
18161                        } catch (RemoteException e) {
18162                            Slog.w(TAG, "Failure ["
18163                                    + queue.mQueueName + "] sending broadcast result of "
18164                                    + intent, e);
18165
18166                        }
18167                    }
18168                    // Lie; we don't want to crash the app.
18169                    return ActivityManager.BROADCAST_SUCCESS;
18170                case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
18171                    mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
18172                    break;
18173            }
18174        }
18175
18176        // Add to the sticky list if requested.
18177        if (sticky) {
18178            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
18179                    callingPid, callingUid)
18180                    != PackageManager.PERMISSION_GRANTED) {
18181                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
18182                        + callingPid + ", uid=" + callingUid
18183                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18184                Slog.w(TAG, msg);
18185                throw new SecurityException(msg);
18186            }
18187            if (requiredPermissions != null && requiredPermissions.length > 0) {
18188                Slog.w(TAG, "Can't broadcast sticky intent " + intent
18189                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
18190                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
18191            }
18192            if (intent.getComponent() != null) {
18193                throw new SecurityException(
18194                        "Sticky broadcasts can't target a specific component");
18195            }
18196            // We use userId directly here, since the "all" target is maintained
18197            // as a separate set of sticky broadcasts.
18198            if (userId != UserHandle.USER_ALL) {
18199                // But first, if this is not a broadcast to all users, then
18200                // make sure it doesn't conflict with an existing broadcast to
18201                // all users.
18202                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
18203                        UserHandle.USER_ALL);
18204                if (stickies != null) {
18205                    ArrayList<Intent> list = stickies.get(intent.getAction());
18206                    if (list != null) {
18207                        int N = list.size();
18208                        int i;
18209                        for (i=0; i<N; i++) {
18210                            if (intent.filterEquals(list.get(i))) {
18211                                throw new IllegalArgumentException(
18212                                        "Sticky broadcast " + intent + " for user "
18213                                        + userId + " conflicts with existing global broadcast");
18214                            }
18215                        }
18216                    }
18217                }
18218            }
18219            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18220            if (stickies == null) {
18221                stickies = new ArrayMap<>();
18222                mStickyBroadcasts.put(userId, stickies);
18223            }
18224            ArrayList<Intent> list = stickies.get(intent.getAction());
18225            if (list == null) {
18226                list = new ArrayList<>();
18227                stickies.put(intent.getAction(), list);
18228            }
18229            final int stickiesCount = list.size();
18230            int i;
18231            for (i = 0; i < stickiesCount; i++) {
18232                if (intent.filterEquals(list.get(i))) {
18233                    // This sticky already exists, replace it.
18234                    list.set(i, new Intent(intent));
18235                    break;
18236                }
18237            }
18238            if (i >= stickiesCount) {
18239                list.add(new Intent(intent));
18240            }
18241        }
18242
18243        int[] users;
18244        if (userId == UserHandle.USER_ALL) {
18245            // Caller wants broadcast to go to all started users.
18246            users = mUserController.getStartedUserArrayLocked();
18247        } else {
18248            // Caller wants broadcast to go to one specific user.
18249            users = new int[] {userId};
18250        }
18251
18252        // Figure out who all will receive this broadcast.
18253        List receivers = null;
18254        List<BroadcastFilter> registeredReceivers = null;
18255        // Need to resolve the intent to interested receivers...
18256        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
18257                 == 0) {
18258            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
18259        }
18260        if (intent.getComponent() == null) {
18261            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
18262                // Query one target user at a time, excluding shell-restricted users
18263                for (int i = 0; i < users.length; i++) {
18264                    if (mUserController.hasUserRestriction(
18265                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
18266                        continue;
18267                    }
18268                    List<BroadcastFilter> registeredReceiversForUser =
18269                            mReceiverResolver.queryIntent(intent,
18270                                    resolvedType, false, users[i]);
18271                    if (registeredReceivers == null) {
18272                        registeredReceivers = registeredReceiversForUser;
18273                    } else if (registeredReceiversForUser != null) {
18274                        registeredReceivers.addAll(registeredReceiversForUser);
18275                    }
18276                }
18277            } else {
18278                registeredReceivers = mReceiverResolver.queryIntent(intent,
18279                        resolvedType, false, userId);
18280            }
18281        }
18282
18283        final boolean replacePending =
18284                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
18285
18286        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
18287                + " replacePending=" + replacePending);
18288
18289        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
18290        if (!ordered && NR > 0) {
18291            // If we are not serializing this broadcast, then send the
18292            // registered receivers separately so they don't wait for the
18293            // components to be launched.
18294            if (isCallerSystem) {
18295                checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18296                        isProtectedBroadcast, registeredReceivers);
18297            }
18298            final BroadcastQueue queue = broadcastQueueForIntent(intent);
18299            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18300                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
18301                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
18302                    resultExtras, ordered, sticky, false, userId);
18303            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
18304            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
18305            if (!replaced) {
18306                queue.enqueueParallelBroadcastLocked(r);
18307                queue.scheduleBroadcastsLocked();
18308            }
18309            registeredReceivers = null;
18310            NR = 0;
18311        }
18312
18313        // Merge into one list.
18314        int ir = 0;
18315        if (receivers != null) {
18316            // A special case for PACKAGE_ADDED: do not allow the package
18317            // being added to see this broadcast.  This prevents them from
18318            // using this as a back door to get run as soon as they are
18319            // installed.  Maybe in the future we want to have a special install
18320            // broadcast or such for apps, but we'd like to deliberately make
18321            // this decision.
18322            String skipPackages[] = null;
18323            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
18324                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
18325                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
18326                Uri data = intent.getData();
18327                if (data != null) {
18328                    String pkgName = data.getSchemeSpecificPart();
18329                    if (pkgName != null) {
18330                        skipPackages = new String[] { pkgName };
18331                    }
18332                }
18333            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18334                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18335            }
18336            if (skipPackages != null && (skipPackages.length > 0)) {
18337                for (String skipPackage : skipPackages) {
18338                    if (skipPackage != null) {
18339                        int NT = receivers.size();
18340                        for (int it=0; it<NT; it++) {
18341                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
18342                            if (curt.activityInfo.packageName.equals(skipPackage)) {
18343                                receivers.remove(it);
18344                                it--;
18345                                NT--;
18346                            }
18347                        }
18348                    }
18349                }
18350            }
18351
18352            int NT = receivers != null ? receivers.size() : 0;
18353            int it = 0;
18354            ResolveInfo curt = null;
18355            BroadcastFilter curr = null;
18356            while (it < NT && ir < NR) {
18357                if (curt == null) {
18358                    curt = (ResolveInfo)receivers.get(it);
18359                }
18360                if (curr == null) {
18361                    curr = registeredReceivers.get(ir);
18362                }
18363                if (curr.getPriority() >= curt.priority) {
18364                    // Insert this broadcast record into the final list.
18365                    receivers.add(it, curr);
18366                    ir++;
18367                    curr = null;
18368                    it++;
18369                    NT++;
18370                } else {
18371                    // Skip to the next ResolveInfo in the final list.
18372                    it++;
18373                    curt = null;
18374                }
18375            }
18376        }
18377        while (ir < NR) {
18378            if (receivers == null) {
18379                receivers = new ArrayList();
18380            }
18381            receivers.add(registeredReceivers.get(ir));
18382            ir++;
18383        }
18384
18385        if (isCallerSystem) {
18386            checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18387                    isProtectedBroadcast, receivers);
18388        }
18389
18390        if ((receivers != null && receivers.size() > 0)
18391                || resultTo != null) {
18392            BroadcastQueue queue = broadcastQueueForIntent(intent);
18393            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18394                    callerPackage, callingPid, callingUid, resolvedType,
18395                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18396                    resultData, resultExtras, ordered, sticky, false, userId);
18397
18398            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18399                    + ": prev had " + queue.mOrderedBroadcasts.size());
18400            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18401                    "Enqueueing broadcast " + r.intent.getAction());
18402
18403            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18404            if (!replaced) {
18405                queue.enqueueOrderedBroadcastLocked(r);
18406                queue.scheduleBroadcastsLocked();
18407            }
18408        } else {
18409            // There was nobody interested in the broadcast, but we still want to record
18410            // that it happened.
18411            if (intent.getComponent() == null && intent.getPackage() == null
18412                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18413                // This was an implicit broadcast... let's record it for posterity.
18414                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18415            }
18416        }
18417
18418        return ActivityManager.BROADCAST_SUCCESS;
18419    }
18420
18421    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18422            int skipCount, long dispatchTime) {
18423        final long now = SystemClock.elapsedRealtime();
18424        if (mCurBroadcastStats == null ||
18425                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18426            mLastBroadcastStats = mCurBroadcastStats;
18427            if (mLastBroadcastStats != null) {
18428                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18429                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18430            }
18431            mCurBroadcastStats = new BroadcastStats();
18432        }
18433        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18434    }
18435
18436    final Intent verifyBroadcastLocked(Intent intent) {
18437        // Refuse possible leaked file descriptors
18438        if (intent != null && intent.hasFileDescriptors() == true) {
18439            throw new IllegalArgumentException("File descriptors passed in Intent");
18440        }
18441
18442        int flags = intent.getFlags();
18443
18444        if (!mProcessesReady) {
18445            // if the caller really truly claims to know what they're doing, go
18446            // ahead and allow the broadcast without launching any receivers
18447            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18448                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18449            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18450                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18451                        + " before boot completion");
18452                throw new IllegalStateException("Cannot broadcast before boot completed");
18453            }
18454        }
18455
18456        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18457            throw new IllegalArgumentException(
18458                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18459        }
18460
18461        return intent;
18462    }
18463
18464    public final int broadcastIntent(IApplicationThread caller,
18465            Intent intent, String resolvedType, IIntentReceiver resultTo,
18466            int resultCode, String resultData, Bundle resultExtras,
18467            String[] requiredPermissions, int appOp, Bundle bOptions,
18468            boolean serialized, boolean sticky, int userId) {
18469        enforceNotIsolatedCaller("broadcastIntent");
18470        synchronized(this) {
18471            intent = verifyBroadcastLocked(intent);
18472
18473            final ProcessRecord callerApp = getRecordForAppLocked(caller);
18474            final int callingPid = Binder.getCallingPid();
18475            final int callingUid = Binder.getCallingUid();
18476            final long origId = Binder.clearCallingIdentity();
18477            int res = broadcastIntentLocked(callerApp,
18478                    callerApp != null ? callerApp.info.packageName : null,
18479                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18480                    requiredPermissions, appOp, bOptions, serialized, sticky,
18481                    callingPid, callingUid, userId);
18482            Binder.restoreCallingIdentity(origId);
18483            return res;
18484        }
18485    }
18486
18487
18488    int broadcastIntentInPackage(String packageName, int uid,
18489            Intent intent, String resolvedType, IIntentReceiver resultTo,
18490            int resultCode, String resultData, Bundle resultExtras,
18491            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18492            int userId) {
18493        synchronized(this) {
18494            intent = verifyBroadcastLocked(intent);
18495
18496            final long origId = Binder.clearCallingIdentity();
18497            String[] requiredPermissions = requiredPermission == null ? null
18498                    : new String[] {requiredPermission};
18499            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18500                    resultTo, resultCode, resultData, resultExtras,
18501                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18502                    sticky, -1, uid, userId);
18503            Binder.restoreCallingIdentity(origId);
18504            return res;
18505        }
18506    }
18507
18508    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18509        // Refuse possible leaked file descriptors
18510        if (intent != null && intent.hasFileDescriptors() == true) {
18511            throw new IllegalArgumentException("File descriptors passed in Intent");
18512        }
18513
18514        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18515                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18516
18517        synchronized(this) {
18518            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18519                    != PackageManager.PERMISSION_GRANTED) {
18520                String msg = "Permission Denial: unbroadcastIntent() from pid="
18521                        + Binder.getCallingPid()
18522                        + ", uid=" + Binder.getCallingUid()
18523                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18524                Slog.w(TAG, msg);
18525                throw new SecurityException(msg);
18526            }
18527            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18528            if (stickies != null) {
18529                ArrayList<Intent> list = stickies.get(intent.getAction());
18530                if (list != null) {
18531                    int N = list.size();
18532                    int i;
18533                    for (i=0; i<N; i++) {
18534                        if (intent.filterEquals(list.get(i))) {
18535                            list.remove(i);
18536                            break;
18537                        }
18538                    }
18539                    if (list.size() <= 0) {
18540                        stickies.remove(intent.getAction());
18541                    }
18542                }
18543                if (stickies.size() <= 0) {
18544                    mStickyBroadcasts.remove(userId);
18545                }
18546            }
18547        }
18548    }
18549
18550    void backgroundServicesFinishedLocked(int userId) {
18551        for (BroadcastQueue queue : mBroadcastQueues) {
18552            queue.backgroundServicesFinishedLocked(userId);
18553        }
18554    }
18555
18556    public void finishReceiver(IBinder who, int resultCode, String resultData,
18557            Bundle resultExtras, boolean resultAbort, int flags) {
18558        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18559
18560        // Refuse possible leaked file descriptors
18561        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18562            throw new IllegalArgumentException("File descriptors passed in Bundle");
18563        }
18564
18565        final long origId = Binder.clearCallingIdentity();
18566        try {
18567            boolean doNext = false;
18568            BroadcastRecord r;
18569
18570            synchronized(this) {
18571                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18572                        ? mFgBroadcastQueue : mBgBroadcastQueue;
18573                r = queue.getMatchingOrderedReceiver(who);
18574                if (r != null) {
18575                    doNext = r.queue.finishReceiverLocked(r, resultCode,
18576                        resultData, resultExtras, resultAbort, true);
18577                }
18578            }
18579
18580            if (doNext) {
18581                r.queue.processNextBroadcast(false);
18582            }
18583            trimApplications();
18584        } finally {
18585            Binder.restoreCallingIdentity(origId);
18586        }
18587    }
18588
18589    // =========================================================
18590    // INSTRUMENTATION
18591    // =========================================================
18592
18593    public boolean startInstrumentation(ComponentName className,
18594            String profileFile, int flags, Bundle arguments,
18595            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18596            int userId, String abiOverride) {
18597        enforceNotIsolatedCaller("startInstrumentation");
18598        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18599                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18600        // Refuse possible leaked file descriptors
18601        if (arguments != null && arguments.hasFileDescriptors()) {
18602            throw new IllegalArgumentException("File descriptors passed in Bundle");
18603        }
18604
18605        synchronized(this) {
18606            InstrumentationInfo ii = null;
18607            ApplicationInfo ai = null;
18608            try {
18609                ii = mContext.getPackageManager().getInstrumentationInfo(
18610                    className, STOCK_PM_FLAGS);
18611                ai = AppGlobals.getPackageManager().getApplicationInfo(
18612                        ii.targetPackage, STOCK_PM_FLAGS, userId);
18613            } catch (PackageManager.NameNotFoundException e) {
18614            } catch (RemoteException e) {
18615            }
18616            if (ii == null) {
18617                reportStartInstrumentationFailureLocked(watcher, className,
18618                        "Unable to find instrumentation info for: " + className);
18619                return false;
18620            }
18621            if (ai == null) {
18622                reportStartInstrumentationFailureLocked(watcher, className,
18623                        "Unable to find instrumentation target package: " + ii.targetPackage);
18624                return false;
18625            }
18626            if (!ai.hasCode()) {
18627                reportStartInstrumentationFailureLocked(watcher, className,
18628                        "Instrumentation target has no code: " + ii.targetPackage);
18629                return false;
18630            }
18631
18632            int match = mContext.getPackageManager().checkSignatures(
18633                    ii.targetPackage, ii.packageName);
18634            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18635                String msg = "Permission Denial: starting instrumentation "
18636                        + className + " from pid="
18637                        + Binder.getCallingPid()
18638                        + ", uid=" + Binder.getCallingPid()
18639                        + " not allowed because package " + ii.packageName
18640                        + " does not have a signature matching the target "
18641                        + ii.targetPackage;
18642                reportStartInstrumentationFailureLocked(watcher, className, msg);
18643                throw new SecurityException(msg);
18644            }
18645
18646            final long origId = Binder.clearCallingIdentity();
18647            // Instrumentation can kill and relaunch even persistent processes
18648            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18649                    "start instr");
18650            ProcessRecord app = addAppLocked(ai, false, abiOverride);
18651            app.instrumentationClass = className;
18652            app.instrumentationInfo = ai;
18653            app.instrumentationProfileFile = profileFile;
18654            app.instrumentationArguments = arguments;
18655            app.instrumentationWatcher = watcher;
18656            app.instrumentationUiAutomationConnection = uiAutomationConnection;
18657            app.instrumentationResultClass = className;
18658            Binder.restoreCallingIdentity(origId);
18659        }
18660
18661        return true;
18662    }
18663
18664    /**
18665     * Report errors that occur while attempting to start Instrumentation.  Always writes the
18666     * error to the logs, but if somebody is watching, send the report there too.  This enables
18667     * the "am" command to report errors with more information.
18668     *
18669     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18670     * @param cn The component name of the instrumentation.
18671     * @param report The error report.
18672     */
18673    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18674            ComponentName cn, String report) {
18675        Slog.w(TAG, report);
18676        if (watcher != null) {
18677            Bundle results = new Bundle();
18678            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18679            results.putString("Error", report);
18680            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18681        }
18682    }
18683
18684    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18685        if (app.instrumentationWatcher != null) {
18686            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18687                    app.instrumentationClass, resultCode, results);
18688        }
18689
18690        // Can't call out of the system process with a lock held, so post a message.
18691        if (app.instrumentationUiAutomationConnection != null) {
18692            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18693                    app.instrumentationUiAutomationConnection).sendToTarget();
18694        }
18695
18696        app.instrumentationWatcher = null;
18697        app.instrumentationUiAutomationConnection = null;
18698        app.instrumentationClass = null;
18699        app.instrumentationInfo = null;
18700        app.instrumentationProfileFile = null;
18701        app.instrumentationArguments = null;
18702
18703        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18704                "finished inst");
18705    }
18706
18707    public void finishInstrumentation(IApplicationThread target,
18708            int resultCode, Bundle results) {
18709        int userId = UserHandle.getCallingUserId();
18710        // Refuse possible leaked file descriptors
18711        if (results != null && results.hasFileDescriptors()) {
18712            throw new IllegalArgumentException("File descriptors passed in Intent");
18713        }
18714
18715        synchronized(this) {
18716            ProcessRecord app = getRecordForAppLocked(target);
18717            if (app == null) {
18718                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18719                return;
18720            }
18721            final long origId = Binder.clearCallingIdentity();
18722            finishInstrumentationLocked(app, resultCode, results);
18723            Binder.restoreCallingIdentity(origId);
18724        }
18725    }
18726
18727    // =========================================================
18728    // CONFIGURATION
18729    // =========================================================
18730
18731    public ConfigurationInfo getDeviceConfigurationInfo() {
18732        ConfigurationInfo config = new ConfigurationInfo();
18733        synchronized (this) {
18734            final Configuration globalConfig = getGlobalConfiguration();
18735            config.reqTouchScreen = globalConfig.touchscreen;
18736            config.reqKeyboardType = globalConfig.keyboard;
18737            config.reqNavigation = globalConfig.navigation;
18738            if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
18739                    || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
18740                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18741            }
18742            if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
18743                    && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
18744                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18745            }
18746            config.reqGlEsVersion = GL_ES_VERSION;
18747        }
18748        return config;
18749    }
18750
18751    ActivityStack getFocusedStack() {
18752        return mStackSupervisor.getFocusedStack();
18753    }
18754
18755    @Override
18756    public int getFocusedStackId() throws RemoteException {
18757        ActivityStack focusedStack = getFocusedStack();
18758        if (focusedStack != null) {
18759            return focusedStack.getStackId();
18760        }
18761        return -1;
18762    }
18763
18764    public Configuration getConfiguration() {
18765        Configuration ci;
18766        synchronized(this) {
18767            ci = new Configuration(getGlobalConfiguration());
18768            ci.userSetLocale = false;
18769        }
18770        return ci;
18771    }
18772
18773    @Override
18774    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18775        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18776        synchronized (this) {
18777            mSuppressResizeConfigChanges = suppress;
18778        }
18779    }
18780
18781    @Override
18782    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18783        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18784        if (fromStackId == HOME_STACK_ID) {
18785            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18786        }
18787        synchronized (this) {
18788            final long origId = Binder.clearCallingIdentity();
18789            try {
18790                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18791            } finally {
18792                Binder.restoreCallingIdentity(origId);
18793            }
18794        }
18795    }
18796
18797    @Override
18798    public void updatePersistentConfiguration(Configuration values) {
18799        enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
18800        enforceWriteSettingsPermission("updatePersistentConfiguration()");
18801        if (values == null) {
18802            throw new NullPointerException("Configuration must not be null");
18803        }
18804
18805        int userId = UserHandle.getCallingUserId();
18806
18807        synchronized(this) {
18808            updatePersistentConfigurationLocked(values, userId);
18809        }
18810    }
18811
18812    private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
18813        final long origId = Binder.clearCallingIdentity();
18814        try {
18815            updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
18816        } finally {
18817            Binder.restoreCallingIdentity(origId);
18818        }
18819    }
18820
18821    private void updateFontScaleIfNeeded(@UserIdInt int userId) {
18822        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18823                FONT_SCALE, 1.0f, userId);
18824
18825        synchronized (this) {
18826            if (getGlobalConfiguration().fontScale == scaleFactor) {
18827                return;
18828            }
18829
18830            final Configuration configuration
18831                    = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
18832            configuration.fontScale = scaleFactor;
18833            updatePersistentConfigurationLocked(configuration, userId);
18834        }
18835    }
18836
18837    private void enforceWriteSettingsPermission(String func) {
18838        int uid = Binder.getCallingUid();
18839        if (uid == Process.ROOT_UID) {
18840            return;
18841        }
18842
18843        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18844                Settings.getPackageNameForUid(mContext, uid), false)) {
18845            return;
18846        }
18847
18848        String msg = "Permission Denial: " + func + " from pid="
18849                + Binder.getCallingPid()
18850                + ", uid=" + uid
18851                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18852        Slog.w(TAG, msg);
18853        throw new SecurityException(msg);
18854    }
18855
18856    @Override
18857    public boolean updateConfiguration(Configuration values) {
18858        enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
18859
18860        synchronized(this) {
18861            if (values == null && mWindowManager != null) {
18862                // sentinel: fetch the current configuration from the window manager
18863                values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
18864            }
18865
18866            if (mWindowManager != null) {
18867                // Update OOM levels based on display size.
18868                mProcessList.applyDisplaySize(mWindowManager);
18869            }
18870
18871            final long origId = Binder.clearCallingIdentity();
18872            try {
18873                if (values != null) {
18874                    Settings.System.clearConfiguration(values);
18875                }
18876                updateConfigurationLocked(values, null, false, false /* persistent */,
18877                        UserHandle.USER_NULL, false /* deferResume */,
18878                        mTmpUpdateConfigurationResult);
18879                return mTmpUpdateConfigurationResult.changes != 0;
18880            } finally {
18881                Binder.restoreCallingIdentity(origId);
18882            }
18883        }
18884    }
18885
18886    void updateUserConfigurationLocked() {
18887        final Configuration configuration = new Configuration(getGlobalConfiguration());
18888        final int currentUserId = mUserController.getCurrentUserIdLocked();
18889        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18890                currentUserId, Settings.System.canWrite(mContext));
18891        updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
18892                false /* persistent */, currentUserId, false /* deferResume */);
18893    }
18894
18895    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18896            boolean initLocale) {
18897        return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
18898    }
18899
18900    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18901            boolean initLocale, boolean deferResume) {
18902        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18903        return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
18904                UserHandle.USER_NULL, deferResume);
18905    }
18906
18907    // To cache the list of supported system locales
18908    private String[] mSupportedSystemLocales = null;
18909
18910    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18911            boolean initLocale, boolean persistent, int userId, boolean deferResume) {
18912        return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
18913                deferResume, null /* result */);
18914    }
18915
18916    /**
18917     * Do either or both things: (1) change the current configuration, and (2)
18918     * make sure the given activity is running with the (now) current
18919     * configuration.  Returns true if the activity has been left running, or
18920     * false if <var>starting</var> is being destroyed to match the new
18921     * configuration.
18922     *
18923     * @param userId is only used when persistent parameter is set to true to persist configuration
18924     *               for that particular user
18925     */
18926    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18927            boolean initLocale, boolean persistent, int userId, boolean deferResume,
18928            UpdateConfigurationResult result) {
18929        int changes = 0;
18930        boolean kept = true;
18931
18932        if (mWindowManager != null) {
18933            mWindowManager.deferSurfaceLayout();
18934        }
18935        try {
18936            if (values != null) {
18937                changes = updateGlobalConfiguration(values, initLocale, persistent, userId,
18938                        deferResume);
18939            }
18940
18941            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
18942        } finally {
18943            if (mWindowManager != null) {
18944                mWindowManager.continueSurfaceLayout();
18945            }
18946        }
18947
18948        if (result != null) {
18949            result.changes = changes;
18950            result.activityRelaunched = !kept;
18951        }
18952        return kept;
18953    }
18954
18955    /** Update default (global) configuration and notify listeners about changes. */
18956    private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale,
18957            boolean persistent, int userId, boolean deferResume) {
18958        mTempConfig.setTo(getGlobalConfiguration());
18959        final int changes = mTempConfig.updateFrom(values);
18960        if (changes == 0) {
18961            return 0;
18962        }
18963
18964        if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18965                "Updating global configuration to: " + values);
18966
18967        EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18968
18969        if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18970            final LocaleList locales = values.getLocales();
18971            int bestLocaleIndex = 0;
18972            if (locales.size() > 1) {
18973                if (mSupportedSystemLocales == null) {
18974                    mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
18975                }
18976                bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
18977            }
18978            SystemProperties.set("persist.sys.locale",
18979                    locales.get(bestLocaleIndex).toLanguageTag());
18980            LocaleList.setDefault(locales, bestLocaleIndex);
18981            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18982                    locales.get(bestLocaleIndex)));
18983        }
18984
18985        mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
18986        mTempConfig.seq = mConfigurationSeq;
18987
18988        // Update stored global config and notify everyone about the change.
18989        mStackSupervisor.onConfigurationChanged(mTempConfig);
18990
18991        Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
18992        // TODO(multi-display): Update UsageEvents#Event to include displayId.
18993        mUsageStatsService.reportConfigurationChange(mTempConfig,
18994                mUserController.getCurrentUserIdLocked());
18995
18996        // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
18997        mShowDialogs = shouldShowDialogs(mTempConfig, mInVrMode);
18998
18999        AttributeCache ac = AttributeCache.instance();
19000        if (ac != null) {
19001            ac.updateConfiguration(mTempConfig);
19002        }
19003
19004        // Make sure all resources in our process are updated right now, so that anyone who is going
19005        // to retrieve resource values after we return will be sure to get the new ones. This is
19006        // especially important during boot, where the first config change needs to guarantee all
19007        // resources have that config before following boot code is executed.
19008        mSystemThread.applyConfigurationToResources(mTempConfig);
19009
19010        // We need another copy of global config because we're scheduling some calls instead of
19011        // running them in place. We need to be sure that object we send will be handled unchanged.
19012        final Configuration configCopy = new Configuration(mTempConfig);
19013        if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
19014            Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
19015            msg.obj = configCopy;
19016            msg.arg1 = userId;
19017            mHandler.sendMessage(msg);
19018        }
19019
19020        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19021            ProcessRecord app = mLruProcesses.get(i);
19022            try {
19023                if (app.thread != null) {
19024                    if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
19025                            + app.processName + " new config " + configCopy);
19026                    app.thread.scheduleConfigurationChanged(configCopy);
19027                }
19028            } catch (Exception e) {
19029            }
19030        }
19031
19032        Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
19033        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
19034                | Intent.FLAG_RECEIVER_FOREGROUND);
19035        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
19036                AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID,
19037                UserHandle.USER_ALL);
19038        if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
19039            intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
19040            intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19041            if (initLocale || !mProcessesReady) {
19042                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19043            }
19044            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
19045                    AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID,
19046                    UserHandle.USER_ALL);
19047        }
19048
19049        // Override configuration of the default display duplicates global config, so we need to
19050        // update it also. This will also notify WindowManager about changes.
19051        performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
19052                DEFAULT_DISPLAY);
19053
19054        return changes;
19055    }
19056
19057    @Override
19058    public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
19059        enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
19060
19061        synchronized (this) {
19062            if (values == null && mWindowManager != null) {
19063                // sentinel: fetch the current configuration from the window manager
19064                values = mWindowManager.computeNewConfiguration(displayId);
19065            }
19066
19067            if (mWindowManager != null) {
19068                // Update OOM levels based on display size.
19069                mProcessList.applyDisplaySize(mWindowManager);
19070            }
19071
19072            final long origId = Binder.clearCallingIdentity();
19073            try {
19074                if (values != null) {
19075                    Settings.System.clearConfiguration(values);
19076                }
19077                updateDisplayOverrideConfigurationLocked(values, null /* starting */,
19078                        false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
19079                return mTmpUpdateConfigurationResult.changes != 0;
19080            } finally {
19081                Binder.restoreCallingIdentity(origId);
19082            }
19083        }
19084    }
19085
19086    boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
19087            boolean deferResume, int displayId) {
19088        return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
19089                displayId, null /* result */);
19090    }
19091
19092    /**
19093     * Updates override configuration specific for the selected display. If no config is provided,
19094     * new one will be computed in WM based on current display info.
19095     */
19096    private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
19097            ActivityRecord starting, boolean deferResume, int displayId,
19098            UpdateConfigurationResult result) {
19099        int changes = 0;
19100        boolean kept = true;
19101
19102        if (mWindowManager != null) {
19103            mWindowManager.deferSurfaceLayout();
19104        }
19105        try {
19106            if (values != null) {
19107                if (displayId == DEFAULT_DISPLAY) {
19108                    // Override configuration of the default display duplicates global config, so
19109                    // we're calling global config update instead for default display. It will also
19110                    // apply the correct override config.
19111                    changes = updateGlobalConfiguration(values, false /* initLocale */,
19112                            false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
19113                } else {
19114                    changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
19115                }
19116            }
19117
19118            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
19119        } finally {
19120            if (mWindowManager != null) {
19121                mWindowManager.continueSurfaceLayout();
19122            }
19123        }
19124
19125        if (result != null) {
19126            result.changes = changes;
19127            result.activityRelaunched = !kept;
19128        }
19129        return kept;
19130    }
19131
19132    private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
19133            int displayId) {
19134        mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
19135        final int changes = mTempConfig.updateFrom(values);
19136        if (changes == 0) {
19137            return 0;
19138        }
19139
19140        Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " " + mTempConfig
19141                + " for displayId=" + displayId);
19142        mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
19143
19144        final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
19145        if (isDensityChange) {
19146            // Reset the unsupported display size dialog.
19147            mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
19148
19149            killAllBackgroundProcessesExcept(N, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
19150        }
19151
19152        // Update the configuration with WM first and check if any of the stacks need to be resized
19153        // due to the configuration change. If so, resize the stacks now and do any relaunches if
19154        // necessary. This way we don't need to relaunch again afterwards in
19155        // ensureActivityConfigurationLocked().
19156        if (mWindowManager != null) {
19157            final int[] resizedStacks =
19158                    mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
19159            if (resizedStacks != null) {
19160                for (int stackId : resizedStacks) {
19161                    resizeStackWithBoundsFromWindowManager(stackId, deferResume);
19162                }
19163            }
19164        }
19165
19166        return changes;
19167    }
19168
19169    /** Applies latest configuration and/or visibility updates if needed. */
19170    private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
19171        boolean kept = true;
19172        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
19173        // mainStack is null during startup.
19174        if (mainStack != null) {
19175            if (changes != 0 && starting == null) {
19176                // If the configuration changed, and the caller is not already
19177                // in the process of starting an activity, then find the top
19178                // activity to check if its configuration needs to change.
19179                starting = mainStack.topRunningActivityLocked();
19180            }
19181
19182            if (starting != null) {
19183                kept = starting.ensureActivityConfigurationLocked(changes,
19184                        false /* preserveWindow */);
19185                // And we need to make sure at this point that all other activities
19186                // are made visible with the correct configuration.
19187                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
19188                        !PRESERVE_WINDOWS);
19189            }
19190        }
19191
19192        return kept;
19193    }
19194
19195    /** Helper method that requests bounds from WM and applies them to stack. */
19196    private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
19197        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
19198        mStackSupervisor.resizeStackLocked(
19199                stackId, newBounds, null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
19200                false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
19201    }
19202
19203    /**
19204     * Decide based on the configuration whether we should show the ANR,
19205     * crash, etc dialogs.  The idea is that if there is no affordance to
19206     * press the on-screen buttons, or the user experience would be more
19207     * greatly impacted than the crash itself, we shouldn't show the dialog.
19208     *
19209     * A thought: SystemUI might also want to get told about this, the Power
19210     * dialog / global actions also might want different behaviors.
19211     */
19212    private static boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
19213        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
19214                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
19215                                   && config.navigation == Configuration.NAVIGATION_NONAV);
19216        int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
19217        final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
19218                && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE)));
19219        return inputMethodExists && uiModeSupportsDialogs && !inVrMode;
19220    }
19221
19222    @Override
19223    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
19224        synchronized (this) {
19225            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
19226            if (srec != null) {
19227                return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
19228            }
19229        }
19230        return false;
19231    }
19232
19233    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
19234            Intent resultData) {
19235
19236        synchronized (this) {
19237            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
19238            if (r != null) {
19239                return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
19240            }
19241            return false;
19242        }
19243    }
19244
19245    public int getLaunchedFromUid(IBinder activityToken) {
19246        ActivityRecord srec;
19247        synchronized (this) {
19248            srec = ActivityRecord.forTokenLocked(activityToken);
19249        }
19250        if (srec == null) {
19251            return -1;
19252        }
19253        return srec.launchedFromUid;
19254    }
19255
19256    public String getLaunchedFromPackage(IBinder activityToken) {
19257        ActivityRecord srec;
19258        synchronized (this) {
19259            srec = ActivityRecord.forTokenLocked(activityToken);
19260        }
19261        if (srec == null) {
19262            return null;
19263        }
19264        return srec.launchedFromPackage;
19265    }
19266
19267    // =========================================================
19268    // LIFETIME MANAGEMENT
19269    // =========================================================
19270
19271    // Returns whether the app is receiving broadcast.
19272    // If receiving, fetch all broadcast queues which the app is
19273    // the current [or imminent] receiver on.
19274    private boolean isReceivingBroadcastLocked(ProcessRecord app,
19275            ArraySet<BroadcastQueue> receivingQueues) {
19276        if (!app.curReceivers.isEmpty()) {
19277            for (BroadcastRecord r : app.curReceivers) {
19278                receivingQueues.add(r.queue);
19279            }
19280            return true;
19281        }
19282
19283        // It's not the current receiver, but it might be starting up to become one
19284        for (BroadcastQueue queue : mBroadcastQueues) {
19285            final BroadcastRecord r = queue.mPendingBroadcast;
19286            if (r != null && r.curApp == app) {
19287                // found it; report which queue it's in
19288                receivingQueues.add(queue);
19289            }
19290        }
19291
19292        return !receivingQueues.isEmpty();
19293    }
19294
19295    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
19296            int targetUid, ComponentName targetComponent, String targetProcess) {
19297        if (!mTrackingAssociations) {
19298            return null;
19299        }
19300        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19301                = mAssociations.get(targetUid);
19302        if (components == null) {
19303            components = new ArrayMap<>();
19304            mAssociations.put(targetUid, components);
19305        }
19306        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19307        if (sourceUids == null) {
19308            sourceUids = new SparseArray<>();
19309            components.put(targetComponent, sourceUids);
19310        }
19311        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19312        if (sourceProcesses == null) {
19313            sourceProcesses = new ArrayMap<>();
19314            sourceUids.put(sourceUid, sourceProcesses);
19315        }
19316        Association ass = sourceProcesses.get(sourceProcess);
19317        if (ass == null) {
19318            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
19319                    targetProcess);
19320            sourceProcesses.put(sourceProcess, ass);
19321        }
19322        ass.mCount++;
19323        ass.mNesting++;
19324        if (ass.mNesting == 1) {
19325            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
19326            ass.mLastState = sourceState;
19327        }
19328        return ass;
19329    }
19330
19331    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
19332            ComponentName targetComponent) {
19333        if (!mTrackingAssociations) {
19334            return;
19335        }
19336        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19337                = mAssociations.get(targetUid);
19338        if (components == null) {
19339            return;
19340        }
19341        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19342        if (sourceUids == null) {
19343            return;
19344        }
19345        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19346        if (sourceProcesses == null) {
19347            return;
19348        }
19349        Association ass = sourceProcesses.get(sourceProcess);
19350        if (ass == null || ass.mNesting <= 0) {
19351            return;
19352        }
19353        ass.mNesting--;
19354        if (ass.mNesting == 0) {
19355            long uptime = SystemClock.uptimeMillis();
19356            ass.mTime += uptime - ass.mStartTime;
19357            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19358                    += uptime - ass.mLastStateUptime;
19359            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
19360        }
19361    }
19362
19363    private void noteUidProcessState(final int uid, final int state) {
19364        mBatteryStatsService.noteUidProcessState(uid, state);
19365        if (mTrackingAssociations) {
19366            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
19367                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
19368                        = mAssociations.valueAt(i1);
19369                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
19370                    SparseArray<ArrayMap<String, Association>> sourceUids
19371                            = targetComponents.valueAt(i2);
19372                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
19373                    if (sourceProcesses != null) {
19374                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
19375                            Association ass = sourceProcesses.valueAt(i4);
19376                            if (ass.mNesting >= 1) {
19377                                // currently associated
19378                                long uptime = SystemClock.uptimeMillis();
19379                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19380                                        += uptime - ass.mLastStateUptime;
19381                                ass.mLastState = state;
19382                                ass.mLastStateUptime = uptime;
19383                            }
19384                        }
19385                    }
19386                }
19387            }
19388        }
19389    }
19390
19391    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
19392            boolean doingAll, long now) {
19393        if (mAdjSeq == app.adjSeq) {
19394            // This adjustment has already been computed.
19395            return app.curRawAdj;
19396        }
19397
19398        if (app.thread == null) {
19399            app.adjSeq = mAdjSeq;
19400            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19401            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19402            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
19403        }
19404
19405        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
19406        app.adjSource = null;
19407        app.adjTarget = null;
19408        app.empty = false;
19409        app.cached = false;
19410
19411        final int activitiesSize = app.activities.size();
19412
19413        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19414            // The max adjustment doesn't allow this app to be anything
19415            // below foreground, so it is not worth doing work for it.
19416            app.adjType = "fixed";
19417            app.adjSeq = mAdjSeq;
19418            app.curRawAdj = app.maxAdj;
19419            app.foregroundActivities = false;
19420            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19421            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
19422            // System processes can do UI, and when they do we want to have
19423            // them trim their memory after the user leaves the UI.  To
19424            // facilitate this, here we need to determine whether or not it
19425            // is currently showing UI.
19426            app.systemNoUi = true;
19427            if (app == TOP_APP) {
19428                app.systemNoUi = false;
19429                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19430                app.adjType = "pers-top-activity";
19431            } else if (app.hasTopUi) {
19432                app.systemNoUi = false;
19433                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19434                app.adjType = "pers-top-ui";
19435            } else if (activitiesSize > 0) {
19436                for (int j = 0; j < activitiesSize; j++) {
19437                    final ActivityRecord r = app.activities.get(j);
19438                    if (r.visible) {
19439                        app.systemNoUi = false;
19440                    }
19441                }
19442            }
19443            if (!app.systemNoUi) {
19444                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
19445            }
19446            return (app.curAdj=app.maxAdj);
19447        }
19448
19449        app.systemNoUi = false;
19450
19451        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
19452
19453        // Determine the importance of the process, starting with most
19454        // important to least, and assign an appropriate OOM adjustment.
19455        int adj;
19456        int schedGroup;
19457        int procState;
19458        boolean foregroundActivities = false;
19459        final ArraySet<BroadcastQueue> queues = new ArraySet<BroadcastQueue>();
19460        if (app == TOP_APP) {
19461            // The last app on the list is the foreground app.
19462            adj = ProcessList.FOREGROUND_APP_ADJ;
19463            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19464            app.adjType = "top-activity";
19465            foregroundActivities = true;
19466            procState = PROCESS_STATE_CUR_TOP;
19467        } else if (app.instrumentationClass != null) {
19468            // Don't want to kill running instrumentation.
19469            adj = ProcessList.FOREGROUND_APP_ADJ;
19470            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19471            app.adjType = "instrumentation";
19472            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19473        } else if (isReceivingBroadcastLocked(app, queues)) {
19474            // An app that is currently receiving a broadcast also
19475            // counts as being in the foreground for OOM killer purposes.
19476            // It's placed in a sched group based on the nature of the
19477            // broadcast as reflected by which queue it's active in.
19478            adj = ProcessList.FOREGROUND_APP_ADJ;
19479            schedGroup = (queues.contains(mFgBroadcastQueue))
19480                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19481            app.adjType = "broadcast";
19482            procState = ActivityManager.PROCESS_STATE_RECEIVER;
19483        } else if (app.executingServices.size() > 0) {
19484            // An app that is currently executing a service callback also
19485            // counts as being in the foreground.
19486            adj = ProcessList.FOREGROUND_APP_ADJ;
19487            schedGroup = app.execServicesFg ?
19488                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19489            app.adjType = "exec-service";
19490            procState = ActivityManager.PROCESS_STATE_SERVICE;
19491            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
19492        } else {
19493            // As far as we know the process is empty.  We may change our mind later.
19494            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19495            // At this point we don't actually know the adjustment.  Use the cached adj
19496            // value that the caller wants us to.
19497            adj = cachedAdj;
19498            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19499            app.cached = true;
19500            app.empty = true;
19501            app.adjType = "cch-empty";
19502        }
19503
19504        // Examine all activities if not already foreground.
19505        if (!foregroundActivities && activitiesSize > 0) {
19506            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
19507            for (int j = 0; j < activitiesSize; j++) {
19508                final ActivityRecord r = app.activities.get(j);
19509                if (r.app != app) {
19510                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
19511                            + " instead of expected " + app);
19512                    if (r.app == null || (r.app.uid == app.uid)) {
19513                        // Only fix things up when they look sane
19514                        r.app = app;
19515                    } else {
19516                        continue;
19517                    }
19518                }
19519                if (r.visible) {
19520                    // App has a visible activity; only upgrade adjustment.
19521                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19522                        adj = ProcessList.VISIBLE_APP_ADJ;
19523                        app.adjType = "visible";
19524                    }
19525                    if (procState > PROCESS_STATE_CUR_TOP) {
19526                        procState = PROCESS_STATE_CUR_TOP;
19527                    }
19528                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19529                    app.cached = false;
19530                    app.empty = false;
19531                    foregroundActivities = true;
19532                    if (r.task != null && minLayer > 0) {
19533                        final int layer = r.task.mLayerRank;
19534                        if (layer >= 0 && minLayer > layer) {
19535                            minLayer = layer;
19536                        }
19537                    }
19538                    break;
19539                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19540                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19541                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19542                        app.adjType = "pausing";
19543                    }
19544                    if (procState > PROCESS_STATE_CUR_TOP) {
19545                        procState = PROCESS_STATE_CUR_TOP;
19546                    }
19547                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19548                    app.cached = false;
19549                    app.empty = false;
19550                    foregroundActivities = true;
19551                } else if (r.state == ActivityState.STOPPING) {
19552                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19553                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19554                        app.adjType = "stopping";
19555                    }
19556                    // For the process state, we will at this point consider the
19557                    // process to be cached.  It will be cached either as an activity
19558                    // or empty depending on whether the activity is finishing.  We do
19559                    // this so that we can treat the process as cached for purposes of
19560                    // memory trimming (determing current memory level, trim command to
19561                    // send to process) since there can be an arbitrary number of stopping
19562                    // processes and they should soon all go into the cached state.
19563                    if (!r.finishing) {
19564                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19565                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19566                        }
19567                    }
19568                    app.cached = false;
19569                    app.empty = false;
19570                    foregroundActivities = true;
19571                } else {
19572                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19573                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19574                        app.adjType = "cch-act";
19575                    }
19576                }
19577            }
19578            if (adj == ProcessList.VISIBLE_APP_ADJ) {
19579                adj += minLayer;
19580            }
19581        }
19582
19583        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19584                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19585            if (app.foregroundServices) {
19586                // The user is aware of this app, so make it visible.
19587                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19588                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19589                app.cached = false;
19590                app.adjType = "fg-service";
19591                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19592            } else if (app.forcingToForeground != null) {
19593                // The user is aware of this app, so make it visible.
19594                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19595                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19596                app.cached = false;
19597                app.adjType = "force-fg";
19598                app.adjSource = app.forcingToForeground;
19599                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19600            }
19601        }
19602
19603        if (app == mHeavyWeightProcess) {
19604            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19605                // We don't want to kill the current heavy-weight process.
19606                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19607                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19608                app.cached = false;
19609                app.adjType = "heavy";
19610            }
19611            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19612                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19613            }
19614        }
19615
19616        if (app == mHomeProcess) {
19617            if (adj > ProcessList.HOME_APP_ADJ) {
19618                // This process is hosting what we currently consider to be the
19619                // home app, so we don't want to let it go into the background.
19620                adj = ProcessList.HOME_APP_ADJ;
19621                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19622                app.cached = false;
19623                app.adjType = "home";
19624            }
19625            if (procState > ActivityManager.PROCESS_STATE_HOME) {
19626                procState = ActivityManager.PROCESS_STATE_HOME;
19627            }
19628        }
19629
19630        if (app == mPreviousProcess && app.activities.size() > 0) {
19631            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19632                // This was the previous process that showed UI to the user.
19633                // We want to try to keep it around more aggressively, to give
19634                // a good experience around switching between two apps.
19635                adj = ProcessList.PREVIOUS_APP_ADJ;
19636                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19637                app.cached = false;
19638                app.adjType = "previous";
19639            }
19640            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19641                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19642            }
19643        }
19644
19645        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19646                + " reason=" + app.adjType);
19647
19648        // By default, we use the computed adjustment.  It may be changed if
19649        // there are applications dependent on our services or providers, but
19650        // this gives us a baseline and makes sure we don't get into an
19651        // infinite recursion.
19652        app.adjSeq = mAdjSeq;
19653        app.curRawAdj = adj;
19654        app.hasStartedServices = false;
19655
19656        if (mBackupTarget != null && app == mBackupTarget.app) {
19657            // If possible we want to avoid killing apps while they're being backed up
19658            if (adj > ProcessList.BACKUP_APP_ADJ) {
19659                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19660                adj = ProcessList.BACKUP_APP_ADJ;
19661                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19662                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19663                }
19664                app.adjType = "backup";
19665                app.cached = false;
19666            }
19667            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19668                procState = ActivityManager.PROCESS_STATE_BACKUP;
19669            }
19670        }
19671
19672        boolean mayBeTop = false;
19673
19674        for (int is = app.services.size()-1;
19675                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19676                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19677                        || procState > ActivityManager.PROCESS_STATE_TOP);
19678                is--) {
19679            ServiceRecord s = app.services.valueAt(is);
19680            if (s.startRequested) {
19681                app.hasStartedServices = true;
19682                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19683                    procState = ActivityManager.PROCESS_STATE_SERVICE;
19684                }
19685                if (app.hasShownUi && app != mHomeProcess) {
19686                    // If this process has shown some UI, let it immediately
19687                    // go to the LRU list because it may be pretty heavy with
19688                    // UI stuff.  We'll tag it with a label just to help
19689                    // debug and understand what is going on.
19690                    if (adj > ProcessList.SERVICE_ADJ) {
19691                        app.adjType = "cch-started-ui-services";
19692                    }
19693                } else {
19694                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19695                        // This service has seen some activity within
19696                        // recent memory, so we will keep its process ahead
19697                        // of the background processes.
19698                        if (adj > ProcessList.SERVICE_ADJ) {
19699                            adj = ProcessList.SERVICE_ADJ;
19700                            app.adjType = "started-services";
19701                            app.cached = false;
19702                        }
19703                    }
19704                    // If we have let the service slide into the background
19705                    // state, still have some text describing what it is doing
19706                    // even though the service no longer has an impact.
19707                    if (adj > ProcessList.SERVICE_ADJ) {
19708                        app.adjType = "cch-started-services";
19709                    }
19710                }
19711            }
19712
19713            for (int conni = s.connections.size()-1;
19714                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19715                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19716                            || procState > ActivityManager.PROCESS_STATE_TOP);
19717                    conni--) {
19718                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19719                for (int i = 0;
19720                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19721                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19722                                || procState > ActivityManager.PROCESS_STATE_TOP);
19723                        i++) {
19724                    // XXX should compute this based on the max of
19725                    // all connected clients.
19726                    ConnectionRecord cr = clist.get(i);
19727                    if (cr.binding.client == app) {
19728                        // Binding to ourself is not interesting.
19729                        continue;
19730                    }
19731
19732                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19733                        ProcessRecord client = cr.binding.client;
19734                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
19735                                TOP_APP, doingAll, now);
19736                        int clientProcState = client.curProcState;
19737                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19738                            // If the other app is cached for any reason, for purposes here
19739                            // we are going to consider it empty.  The specific cached state
19740                            // doesn't propagate except under certain conditions.
19741                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19742                        }
19743                        String adjType = null;
19744                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19745                            // Not doing bind OOM management, so treat
19746                            // this guy more like a started service.
19747                            if (app.hasShownUi && app != mHomeProcess) {
19748                                // If this process has shown some UI, let it immediately
19749                                // go to the LRU list because it may be pretty heavy with
19750                                // UI stuff.  We'll tag it with a label just to help
19751                                // debug and understand what is going on.
19752                                if (adj > clientAdj) {
19753                                    adjType = "cch-bound-ui-services";
19754                                }
19755                                app.cached = false;
19756                                clientAdj = adj;
19757                                clientProcState = procState;
19758                            } else {
19759                                if (now >= (s.lastActivity
19760                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19761                                    // This service has not seen activity within
19762                                    // recent memory, so allow it to drop to the
19763                                    // LRU list if there is no other reason to keep
19764                                    // it around.  We'll also tag it with a label just
19765                                    // to help debug and undertand what is going on.
19766                                    if (adj > clientAdj) {
19767                                        adjType = "cch-bound-services";
19768                                    }
19769                                    clientAdj = adj;
19770                                }
19771                            }
19772                        }
19773                        if (adj > clientAdj) {
19774                            // If this process has recently shown UI, and
19775                            // the process that is binding to it is less
19776                            // important than being visible, then we don't
19777                            // care about the binding as much as we care
19778                            // about letting this process get into the LRU
19779                            // list to be killed and restarted if needed for
19780                            // memory.
19781                            if (app.hasShownUi && app != mHomeProcess
19782                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19783                                adjType = "cch-bound-ui-services";
19784                            } else {
19785                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19786                                        |Context.BIND_IMPORTANT)) != 0) {
19787                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19788                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19789                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19790                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19791                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19792                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19793                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19794                                    adj = clientAdj;
19795                                } else {
19796                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19797                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19798                                    }
19799                                }
19800                                if (!client.cached) {
19801                                    app.cached = false;
19802                                }
19803                                adjType = "service";
19804                            }
19805                        }
19806                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19807                            // This will treat important bound services identically to
19808                            // the top app, which may behave differently than generic
19809                            // foreground work.
19810                            if (client.curSchedGroup > schedGroup) {
19811                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19812                                    schedGroup = client.curSchedGroup;
19813                                } else {
19814                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19815                                }
19816                            }
19817                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19818                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19819                                    // Special handling of clients who are in the top state.
19820                                    // We *may* want to consider this process to be in the
19821                                    // top state as well, but only if there is not another
19822                                    // reason for it to be running.  Being on the top is a
19823                                    // special state, meaning you are specifically running
19824                                    // for the current top app.  If the process is already
19825                                    // running in the background for some other reason, it
19826                                    // is more important to continue considering it to be
19827                                    // in the background state.
19828                                    mayBeTop = true;
19829                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19830                                } else {
19831                                    // Special handling for above-top states (persistent
19832                                    // processes).  These should not bring the current process
19833                                    // into the top state, since they are not on top.  Instead
19834                                    // give them the best state after that.
19835                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19836                                        clientProcState =
19837                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19838                                    } else if (mWakefulness
19839                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19840                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19841                                                    != 0) {
19842                                        clientProcState =
19843                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19844                                    } else {
19845                                        clientProcState =
19846                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19847                                    }
19848                                }
19849                            }
19850                        } else {
19851                            if (clientProcState <
19852                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19853                                clientProcState =
19854                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19855                            }
19856                        }
19857                        if (procState > clientProcState) {
19858                            procState = clientProcState;
19859                        }
19860                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19861                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19862                            app.pendingUiClean = true;
19863                        }
19864                        if (adjType != null) {
19865                            app.adjType = adjType;
19866                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19867                                    .REASON_SERVICE_IN_USE;
19868                            app.adjSource = cr.binding.client;
19869                            app.adjSourceProcState = clientProcState;
19870                            app.adjTarget = s.name;
19871                        }
19872                    }
19873                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19874                        app.treatLikeActivity = true;
19875                    }
19876                    final ActivityRecord a = cr.activity;
19877                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19878                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19879                            (a.visible || a.state == ActivityState.RESUMED ||
19880                             a.state == ActivityState.PAUSING)) {
19881                            adj = ProcessList.FOREGROUND_APP_ADJ;
19882                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19883                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19884                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
19885                                } else {
19886                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19887                                }
19888                            }
19889                            app.cached = false;
19890                            app.adjType = "service";
19891                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19892                                    .REASON_SERVICE_IN_USE;
19893                            app.adjSource = a;
19894                            app.adjSourceProcState = procState;
19895                            app.adjTarget = s.name;
19896                        }
19897                    }
19898                }
19899            }
19900        }
19901
19902        for (int provi = app.pubProviders.size()-1;
19903                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19904                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19905                        || procState > ActivityManager.PROCESS_STATE_TOP);
19906                provi--) {
19907            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19908            for (int i = cpr.connections.size()-1;
19909                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19910                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19911                            || procState > ActivityManager.PROCESS_STATE_TOP);
19912                    i--) {
19913                ContentProviderConnection conn = cpr.connections.get(i);
19914                ProcessRecord client = conn.client;
19915                if (client == app) {
19916                    // Being our own client is not interesting.
19917                    continue;
19918                }
19919                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19920                int clientProcState = client.curProcState;
19921                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19922                    // If the other app is cached for any reason, for purposes here
19923                    // we are going to consider it empty.
19924                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19925                }
19926                if (adj > clientAdj) {
19927                    if (app.hasShownUi && app != mHomeProcess
19928                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19929                        app.adjType = "cch-ui-provider";
19930                    } else {
19931                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19932                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19933                        app.adjType = "provider";
19934                    }
19935                    app.cached &= client.cached;
19936                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19937                            .REASON_PROVIDER_IN_USE;
19938                    app.adjSource = client;
19939                    app.adjSourceProcState = clientProcState;
19940                    app.adjTarget = cpr.name;
19941                }
19942                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19943                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19944                        // Special handling of clients who are in the top state.
19945                        // We *may* want to consider this process to be in the
19946                        // top state as well, but only if there is not another
19947                        // reason for it to be running.  Being on the top is a
19948                        // special state, meaning you are specifically running
19949                        // for the current top app.  If the process is already
19950                        // running in the background for some other reason, it
19951                        // is more important to continue considering it to be
19952                        // in the background state.
19953                        mayBeTop = true;
19954                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19955                    } else {
19956                        // Special handling for above-top states (persistent
19957                        // processes).  These should not bring the current process
19958                        // into the top state, since they are not on top.  Instead
19959                        // give them the best state after that.
19960                        clientProcState =
19961                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19962                    }
19963                }
19964                if (procState > clientProcState) {
19965                    procState = clientProcState;
19966                }
19967                if (client.curSchedGroup > schedGroup) {
19968                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19969                }
19970            }
19971            // If the provider has external (non-framework) process
19972            // dependencies, ensure that its adjustment is at least
19973            // FOREGROUND_APP_ADJ.
19974            if (cpr.hasExternalProcessHandles()) {
19975                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19976                    adj = ProcessList.FOREGROUND_APP_ADJ;
19977                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19978                    app.cached = false;
19979                    app.adjType = "provider";
19980                    app.adjTarget = cpr.name;
19981                }
19982                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19983                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19984                }
19985            }
19986        }
19987
19988        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19989            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19990                adj = ProcessList.PREVIOUS_APP_ADJ;
19991                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19992                app.cached = false;
19993                app.adjType = "provider";
19994            }
19995            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19996                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19997            }
19998        }
19999
20000        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
20001            // A client of one of our services or providers is in the top state.  We
20002            // *may* want to be in the top state, but not if we are already running in
20003            // the background for some other reason.  For the decision here, we are going
20004            // to pick out a few specific states that we want to remain in when a client
20005            // is top (states that tend to be longer-term) and otherwise allow it to go
20006            // to the top state.
20007            switch (procState) {
20008                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
20009                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
20010                case ActivityManager.PROCESS_STATE_SERVICE:
20011                    // These all are longer-term states, so pull them up to the top
20012                    // of the background states, but not all the way to the top state.
20013                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
20014                    break;
20015                default:
20016                    // Otherwise, top is a better choice, so take it.
20017                    procState = ActivityManager.PROCESS_STATE_TOP;
20018                    break;
20019            }
20020        }
20021
20022        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
20023            if (app.hasClientActivities) {
20024                // This is a cached process, but with client activities.  Mark it so.
20025                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
20026                app.adjType = "cch-client-act";
20027            } else if (app.treatLikeActivity) {
20028                // This is a cached process, but somebody wants us to treat it like it has
20029                // an activity, okay!
20030                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
20031                app.adjType = "cch-as-act";
20032            }
20033        }
20034
20035        if (adj == ProcessList.SERVICE_ADJ) {
20036            if (doingAll) {
20037                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
20038                mNewNumServiceProcs++;
20039                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
20040                if (!app.serviceb) {
20041                    // This service isn't far enough down on the LRU list to
20042                    // normally be a B service, but if we are low on RAM and it
20043                    // is large we want to force it down since we would prefer to
20044                    // keep launcher over it.
20045                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
20046                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
20047                        app.serviceHighRam = true;
20048                        app.serviceb = true;
20049                        //Slog.i(TAG, "ADJ " + app + " high ram!");
20050                    } else {
20051                        mNewNumAServiceProcs++;
20052                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
20053                    }
20054                } else {
20055                    app.serviceHighRam = false;
20056                }
20057            }
20058            if (app.serviceb) {
20059                adj = ProcessList.SERVICE_B_ADJ;
20060            }
20061        }
20062
20063        app.curRawAdj = adj;
20064
20065        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
20066        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
20067        if (adj > app.maxAdj) {
20068            adj = app.maxAdj;
20069            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
20070                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20071            }
20072        }
20073
20074        // Do final modification to adj.  Everything we do between here and applying
20075        // the final setAdj must be done in this function, because we will also use
20076        // it when computing the final cached adj later.  Note that we don't need to
20077        // worry about this for max adj above, since max adj will always be used to
20078        // keep it out of the cached vaues.
20079        app.curAdj = app.modifyRawOomAdj(adj);
20080        app.curSchedGroup = schedGroup;
20081        app.curProcState = procState;
20082        app.foregroundActivities = foregroundActivities;
20083
20084        return app.curRawAdj;
20085    }
20086
20087    /**
20088     * Record new PSS sample for a process.
20089     */
20090    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
20091            long now) {
20092        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
20093                swapPss * 1024);
20094        proc.lastPssTime = now;
20095        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
20096        if (DEBUG_PSS) Slog.d(TAG_PSS,
20097                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
20098                + " state=" + ProcessList.makeProcStateString(procState));
20099        if (proc.initialIdlePss == 0) {
20100            proc.initialIdlePss = pss;
20101        }
20102        proc.lastPss = pss;
20103        proc.lastSwapPss = swapPss;
20104        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
20105            proc.lastCachedPss = pss;
20106            proc.lastCachedSwapPss = swapPss;
20107        }
20108
20109        final SparseArray<Pair<Long, String>> watchUids
20110                = mMemWatchProcesses.getMap().get(proc.processName);
20111        Long check = null;
20112        if (watchUids != null) {
20113            Pair<Long, String> val = watchUids.get(proc.uid);
20114            if (val == null) {
20115                val = watchUids.get(0);
20116            }
20117            if (val != null) {
20118                check = val.first;
20119            }
20120        }
20121        if (check != null) {
20122            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
20123                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20124                if (!isDebuggable) {
20125                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
20126                        isDebuggable = true;
20127                    }
20128                }
20129                if (isDebuggable) {
20130                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
20131                    final ProcessRecord myProc = proc;
20132                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
20133                    mMemWatchDumpProcName = proc.processName;
20134                    mMemWatchDumpFile = heapdumpFile.toString();
20135                    mMemWatchDumpPid = proc.pid;
20136                    mMemWatchDumpUid = proc.uid;
20137                    BackgroundThread.getHandler().post(new Runnable() {
20138                        @Override
20139                        public void run() {
20140                            revokeUriPermission(ActivityThread.currentActivityThread()
20141                                            .getApplicationThread(),
20142                                    DumpHeapActivity.JAVA_URI,
20143                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
20144                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
20145                                    UserHandle.myUserId());
20146                            ParcelFileDescriptor fd = null;
20147                            try {
20148                                heapdumpFile.delete();
20149                                fd = ParcelFileDescriptor.open(heapdumpFile,
20150                                        ParcelFileDescriptor.MODE_CREATE |
20151                                                ParcelFileDescriptor.MODE_TRUNCATE |
20152                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
20153                                                ParcelFileDescriptor.MODE_APPEND);
20154                                IApplicationThread thread = myProc.thread;
20155                                if (thread != null) {
20156                                    try {
20157                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
20158                                                "Requesting dump heap from "
20159                                                + myProc + " to " + heapdumpFile);
20160                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
20161                                    } catch (RemoteException e) {
20162                                    }
20163                                }
20164                            } catch (FileNotFoundException e) {
20165                                e.printStackTrace();
20166                            } finally {
20167                                if (fd != null) {
20168                                    try {
20169                                        fd.close();
20170                                    } catch (IOException e) {
20171                                    }
20172                                }
20173                            }
20174                        }
20175                    });
20176                } else {
20177                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
20178                            + ", but debugging not enabled");
20179                }
20180            }
20181        }
20182    }
20183
20184    /**
20185     * Schedule PSS collection of a process.
20186     */
20187    void requestPssLocked(ProcessRecord proc, int procState) {
20188        if (mPendingPssProcesses.contains(proc)) {
20189            return;
20190        }
20191        if (mPendingPssProcesses.size() == 0) {
20192            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20193        }
20194        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
20195        proc.pssProcState = procState;
20196        mPendingPssProcesses.add(proc);
20197    }
20198
20199    /**
20200     * Schedule PSS collection of all processes.
20201     */
20202    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
20203        if (!always) {
20204            if (now < (mLastFullPssTime +
20205                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
20206                return;
20207            }
20208        }
20209        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
20210        mLastFullPssTime = now;
20211        mFullPssPending = true;
20212        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
20213        mPendingPssProcesses.clear();
20214        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20215            ProcessRecord app = mLruProcesses.get(i);
20216            if (app.thread == null
20217                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
20218                continue;
20219            }
20220            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
20221                app.pssProcState = app.setProcState;
20222                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20223                        mTestPssMode, isSleepingLocked(), now);
20224                mPendingPssProcesses.add(app);
20225            }
20226        }
20227        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20228    }
20229
20230    public void setTestPssMode(boolean enabled) {
20231        synchronized (this) {
20232            mTestPssMode = enabled;
20233            if (enabled) {
20234                // Whenever we enable the mode, we want to take a snapshot all of current
20235                // process mem use.
20236                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
20237            }
20238        }
20239    }
20240
20241    /**
20242     * Ask a given process to GC right now.
20243     */
20244    final void performAppGcLocked(ProcessRecord app) {
20245        try {
20246            app.lastRequestedGc = SystemClock.uptimeMillis();
20247            if (app.thread != null) {
20248                if (app.reportLowMemory) {
20249                    app.reportLowMemory = false;
20250                    app.thread.scheduleLowMemory();
20251                } else {
20252                    app.thread.processInBackground();
20253                }
20254            }
20255        } catch (Exception e) {
20256            // whatever.
20257        }
20258    }
20259
20260    /**
20261     * Returns true if things are idle enough to perform GCs.
20262     */
20263    private final boolean canGcNowLocked() {
20264        boolean processingBroadcasts = false;
20265        for (BroadcastQueue q : mBroadcastQueues) {
20266            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
20267                processingBroadcasts = true;
20268            }
20269        }
20270        return !processingBroadcasts
20271                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
20272    }
20273
20274    /**
20275     * Perform GCs on all processes that are waiting for it, but only
20276     * if things are idle.
20277     */
20278    final void performAppGcsLocked() {
20279        final int N = mProcessesToGc.size();
20280        if (N <= 0) {
20281            return;
20282        }
20283        if (canGcNowLocked()) {
20284            while (mProcessesToGc.size() > 0) {
20285                ProcessRecord proc = mProcessesToGc.remove(0);
20286                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
20287                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
20288                            <= SystemClock.uptimeMillis()) {
20289                        // To avoid spamming the system, we will GC processes one
20290                        // at a time, waiting a few seconds between each.
20291                        performAppGcLocked(proc);
20292                        scheduleAppGcsLocked();
20293                        return;
20294                    } else {
20295                        // It hasn't been long enough since we last GCed this
20296                        // process...  put it in the list to wait for its time.
20297                        addProcessToGcListLocked(proc);
20298                        break;
20299                    }
20300                }
20301            }
20302
20303            scheduleAppGcsLocked();
20304        }
20305    }
20306
20307    /**
20308     * If all looks good, perform GCs on all processes waiting for them.
20309     */
20310    final void performAppGcsIfAppropriateLocked() {
20311        if (canGcNowLocked()) {
20312            performAppGcsLocked();
20313            return;
20314        }
20315        // Still not idle, wait some more.
20316        scheduleAppGcsLocked();
20317    }
20318
20319    /**
20320     * Schedule the execution of all pending app GCs.
20321     */
20322    final void scheduleAppGcsLocked() {
20323        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
20324
20325        if (mProcessesToGc.size() > 0) {
20326            // Schedule a GC for the time to the next process.
20327            ProcessRecord proc = mProcessesToGc.get(0);
20328            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
20329
20330            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
20331            long now = SystemClock.uptimeMillis();
20332            if (when < (now+GC_TIMEOUT)) {
20333                when = now + GC_TIMEOUT;
20334            }
20335            mHandler.sendMessageAtTime(msg, when);
20336        }
20337    }
20338
20339    /**
20340     * Add a process to the array of processes waiting to be GCed.  Keeps the
20341     * list in sorted order by the last GC time.  The process can't already be
20342     * on the list.
20343     */
20344    final void addProcessToGcListLocked(ProcessRecord proc) {
20345        boolean added = false;
20346        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
20347            if (mProcessesToGc.get(i).lastRequestedGc <
20348                    proc.lastRequestedGc) {
20349                added = true;
20350                mProcessesToGc.add(i+1, proc);
20351                break;
20352            }
20353        }
20354        if (!added) {
20355            mProcessesToGc.add(0, proc);
20356        }
20357    }
20358
20359    /**
20360     * Set up to ask a process to GC itself.  This will either do it
20361     * immediately, or put it on the list of processes to gc the next
20362     * time things are idle.
20363     */
20364    final void scheduleAppGcLocked(ProcessRecord app) {
20365        long now = SystemClock.uptimeMillis();
20366        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
20367            return;
20368        }
20369        if (!mProcessesToGc.contains(app)) {
20370            addProcessToGcListLocked(app);
20371            scheduleAppGcsLocked();
20372        }
20373    }
20374
20375    final void checkExcessivePowerUsageLocked(boolean doKills) {
20376        updateCpuStatsNow();
20377
20378        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20379        boolean doWakeKills = doKills;
20380        boolean doCpuKills = doKills;
20381        if (mLastPowerCheckRealtime == 0) {
20382            doWakeKills = false;
20383        }
20384        if (mLastPowerCheckUptime == 0) {
20385            doCpuKills = false;
20386        }
20387        if (stats.isScreenOn()) {
20388            doWakeKills = false;
20389        }
20390        final long curRealtime = SystemClock.elapsedRealtime();
20391        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
20392        final long curUptime = SystemClock.uptimeMillis();
20393        final long uptimeSince = curUptime - mLastPowerCheckUptime;
20394        mLastPowerCheckRealtime = curRealtime;
20395        mLastPowerCheckUptime = curUptime;
20396        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
20397            doWakeKills = false;
20398        }
20399        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
20400            doCpuKills = false;
20401        }
20402        int i = mLruProcesses.size();
20403        while (i > 0) {
20404            i--;
20405            ProcessRecord app = mLruProcesses.get(i);
20406            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20407                long wtime;
20408                synchronized (stats) {
20409                    wtime = stats.getProcessWakeTime(app.info.uid,
20410                            app.pid, curRealtime);
20411                }
20412                long wtimeUsed = wtime - app.lastWakeTime;
20413                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
20414                if (DEBUG_POWER) {
20415                    StringBuilder sb = new StringBuilder(128);
20416                    sb.append("Wake for ");
20417                    app.toShortString(sb);
20418                    sb.append(": over ");
20419                    TimeUtils.formatDuration(realtimeSince, sb);
20420                    sb.append(" used ");
20421                    TimeUtils.formatDuration(wtimeUsed, sb);
20422                    sb.append(" (");
20423                    sb.append((wtimeUsed*100)/realtimeSince);
20424                    sb.append("%)");
20425                    Slog.i(TAG_POWER, sb.toString());
20426                    sb.setLength(0);
20427                    sb.append("CPU for ");
20428                    app.toShortString(sb);
20429                    sb.append(": over ");
20430                    TimeUtils.formatDuration(uptimeSince, sb);
20431                    sb.append(" used ");
20432                    TimeUtils.formatDuration(cputimeUsed, sb);
20433                    sb.append(" (");
20434                    sb.append((cputimeUsed*100)/uptimeSince);
20435                    sb.append("%)");
20436                    Slog.i(TAG_POWER, sb.toString());
20437                }
20438                // If a process has held a wake lock for more
20439                // than 50% of the time during this period,
20440                // that sounds bad.  Kill!
20441                if (doWakeKills && realtimeSince > 0
20442                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
20443                    synchronized (stats) {
20444                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
20445                                realtimeSince, wtimeUsed);
20446                    }
20447                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
20448                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
20449                } else if (doCpuKills && uptimeSince > 0
20450                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
20451                    synchronized (stats) {
20452                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
20453                                uptimeSince, cputimeUsed);
20454                    }
20455                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
20456                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
20457                } else {
20458                    app.lastWakeTime = wtime;
20459                    app.lastCpuTime = app.curCpuTime;
20460                }
20461            }
20462        }
20463    }
20464
20465    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
20466            long nowElapsed) {
20467        boolean success = true;
20468
20469        if (app.curRawAdj != app.setRawAdj) {
20470            app.setRawAdj = app.curRawAdj;
20471        }
20472
20473        int changes = 0;
20474
20475        if (app.curAdj != app.setAdj) {
20476            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
20477            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20478                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
20479                    + app.adjType);
20480            app.setAdj = app.curAdj;
20481            app.verifiedAdj = ProcessList.INVALID_ADJ;
20482        }
20483
20484        if (app.setSchedGroup != app.curSchedGroup) {
20485            int oldSchedGroup = app.setSchedGroup;
20486            app.setSchedGroup = app.curSchedGroup;
20487            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20488                    "Setting sched group of " + app.processName
20489                    + " to " + app.curSchedGroup);
20490            if (app.waitingToKill != null && app.curReceivers.isEmpty()
20491                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
20492                app.kill(app.waitingToKill, true);
20493                success = false;
20494            } else {
20495                int processGroup;
20496                switch (app.curSchedGroup) {
20497                    case ProcessList.SCHED_GROUP_BACKGROUND:
20498                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
20499                        break;
20500                    case ProcessList.SCHED_GROUP_TOP_APP:
20501                    case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
20502                        processGroup = Process.THREAD_GROUP_TOP_APP;
20503                        break;
20504                    default:
20505                        processGroup = Process.THREAD_GROUP_DEFAULT;
20506                        break;
20507                }
20508                long oldId = Binder.clearCallingIdentity();
20509                try {
20510                    Process.setProcessGroup(app.pid, processGroup);
20511                    if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
20512                        // do nothing if we already switched to RT
20513                        if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20514                            // Switch VR thread for app to SCHED_FIFO
20515                            if (mInVrMode && app.vrThreadTid != 0) {
20516                                try {
20517                                    Process.setThreadScheduler(app.vrThreadTid,
20518                                        Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20519                                } catch (IllegalArgumentException e) {
20520                                    // thread died, ignore
20521                                }
20522                            }
20523                            if (mUseFifoUiScheduling) {
20524                                // Switch UI pipeline for app to SCHED_FIFO
20525                                app.savedPriority = Process.getThreadPriority(app.pid);
20526                                try {
20527                                    Process.setThreadScheduler(app.pid,
20528                                        Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20529                                } catch (IllegalArgumentException e) {
20530                                    // thread died, ignore
20531                                }
20532                                if (app.renderThreadTid != 0) {
20533                                    try {
20534                                        Process.setThreadScheduler(app.renderThreadTid,
20535                                            Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20536                                    } catch (IllegalArgumentException e) {
20537                                        // thread died, ignore
20538                                    }
20539                                    if (DEBUG_OOM_ADJ) {
20540                                        Slog.d("UI_FIFO", "Set RenderThread (TID " +
20541                                            app.renderThreadTid + ") to FIFO");
20542                                    }
20543                                } else {
20544                                    if (DEBUG_OOM_ADJ) {
20545                                        Slog.d("UI_FIFO", "Not setting RenderThread TID");
20546                                    }
20547                                }
20548                            } else {
20549                                // Boost priority for top app UI and render threads
20550                                Process.setThreadPriority(app.pid, -10);
20551                                if (app.renderThreadTid != 0) {
20552                                    try {
20553                                        Process.setThreadPriority(app.renderThreadTid, -10);
20554                                    } catch (IllegalArgumentException e) {
20555                                        // thread died, ignore
20556                                    }
20557                                }
20558                            }
20559                        }
20560                    } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
20561                               app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20562                        // Reset VR thread to SCHED_OTHER
20563                        // Safe to do even if we're not in VR mode
20564                        if (app.vrThreadTid != 0) {
20565                            Process.setThreadScheduler(app.vrThreadTid, Process.SCHED_OTHER, 0);
20566                        }
20567                        if (mUseFifoUiScheduling) {
20568                            // Reset UI pipeline to SCHED_OTHER
20569                            Process.setThreadScheduler(app.pid, Process.SCHED_OTHER, 0);
20570                            Process.setThreadPriority(app.pid, app.savedPriority);
20571                            if (app.renderThreadTid != 0) {
20572                                Process.setThreadScheduler(app.renderThreadTid,
20573                                    Process.SCHED_OTHER, 0);
20574                                Process.setThreadPriority(app.renderThreadTid, -4);
20575                            }
20576                        } else {
20577                            // Reset priority for top app UI and render threads
20578                            Process.setThreadPriority(app.pid, 0);
20579                            if (app.renderThreadTid != 0) {
20580                                Process.setThreadPriority(app.renderThreadTid, 0);
20581                            }
20582                        }
20583                    }
20584                } catch (Exception e) {
20585                    Slog.w(TAG, "Failed setting process group of " + app.pid
20586                            + " to " + app.curSchedGroup);
20587                    e.printStackTrace();
20588                } finally {
20589                    Binder.restoreCallingIdentity(oldId);
20590                }
20591            }
20592        }
20593        if (app.repForegroundActivities != app.foregroundActivities) {
20594            app.repForegroundActivities = app.foregroundActivities;
20595            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20596        }
20597        if (app.repProcState != app.curProcState) {
20598            app.repProcState = app.curProcState;
20599            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20600            if (app.thread != null) {
20601                try {
20602                    if (false) {
20603                        //RuntimeException h = new RuntimeException("here");
20604                        Slog.i(TAG, "Sending new process state " + app.repProcState
20605                                + " to " + app /*, h*/);
20606                    }
20607                    app.thread.setProcessState(app.repProcState);
20608                } catch (RemoteException e) {
20609                }
20610            }
20611        }
20612        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20613                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20614            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20615                // Experimental code to more aggressively collect pss while
20616                // running test...  the problem is that this tends to collect
20617                // the data right when a process is transitioning between process
20618                // states, which well tend to give noisy data.
20619                long start = SystemClock.uptimeMillis();
20620                long pss = Debug.getPss(app.pid, mTmpLong, null);
20621                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20622                mPendingPssProcesses.remove(app);
20623                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20624                        + " to " + app.curProcState + ": "
20625                        + (SystemClock.uptimeMillis()-start) + "ms");
20626            }
20627            app.lastStateTime = now;
20628            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20629                    mTestPssMode, isSleepingLocked(), now);
20630            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20631                    + ProcessList.makeProcStateString(app.setProcState) + " to "
20632                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20633                    + (app.nextPssTime-now) + ": " + app);
20634        } else {
20635            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20636                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20637                    mTestPssMode)))) {
20638                requestPssLocked(app, app.setProcState);
20639                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20640                        mTestPssMode, isSleepingLocked(), now);
20641            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20642                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20643        }
20644        if (app.setProcState != app.curProcState) {
20645            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20646                    "Proc state change of " + app.processName
20647                            + " to " + app.curProcState);
20648            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20649            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20650            if (setImportant && !curImportant) {
20651                // This app is no longer something we consider important enough to allow to
20652                // use arbitrary amounts of battery power.  Note
20653                // its current wake lock time to later know to kill it if
20654                // it is not behaving well.
20655                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20656                synchronized (stats) {
20657                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20658                            app.pid, nowElapsed);
20659                }
20660                app.lastCpuTime = app.curCpuTime;
20661
20662            }
20663            // Inform UsageStats of important process state change
20664            // Must be called before updating setProcState
20665            maybeUpdateUsageStatsLocked(app, nowElapsed);
20666
20667            app.setProcState = app.curProcState;
20668            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20669                app.notCachedSinceIdle = false;
20670            }
20671            if (!doingAll) {
20672                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20673            } else {
20674                app.procStateChanged = true;
20675            }
20676        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20677                > USAGE_STATS_INTERACTION_INTERVAL) {
20678            // For apps that sit around for a long time in the interactive state, we need
20679            // to report this at least once a day so they don't go idle.
20680            maybeUpdateUsageStatsLocked(app, nowElapsed);
20681        }
20682
20683        if (changes != 0) {
20684            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20685                    "Changes in " + app + ": " + changes);
20686            int i = mPendingProcessChanges.size()-1;
20687            ProcessChangeItem item = null;
20688            while (i >= 0) {
20689                item = mPendingProcessChanges.get(i);
20690                if (item.pid == app.pid) {
20691                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20692                            "Re-using existing item: " + item);
20693                    break;
20694                }
20695                i--;
20696            }
20697            if (i < 0) {
20698                // No existing item in pending changes; need a new one.
20699                final int NA = mAvailProcessChanges.size();
20700                if (NA > 0) {
20701                    item = mAvailProcessChanges.remove(NA-1);
20702                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20703                            "Retrieving available item: " + item);
20704                } else {
20705                    item = new ProcessChangeItem();
20706                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20707                            "Allocating new item: " + item);
20708                }
20709                item.changes = 0;
20710                item.pid = app.pid;
20711                item.uid = app.info.uid;
20712                if (mPendingProcessChanges.size() == 0) {
20713                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20714                            "*** Enqueueing dispatch processes changed!");
20715                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20716                }
20717                mPendingProcessChanges.add(item);
20718            }
20719            item.changes |= changes;
20720            item.processState = app.repProcState;
20721            item.foregroundActivities = app.repForegroundActivities;
20722            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20723                    "Item " + Integer.toHexString(System.identityHashCode(item))
20724                    + " " + app.toShortString() + ": changes=" + item.changes
20725                    + " procState=" + item.processState
20726                    + " foreground=" + item.foregroundActivities
20727                    + " type=" + app.adjType + " source=" + app.adjSource
20728                    + " target=" + app.adjTarget);
20729        }
20730
20731        return success;
20732    }
20733
20734    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20735        final UidRecord.ChangeItem pendingChange;
20736        if (uidRec == null || uidRec.pendingChange == null) {
20737            if (mPendingUidChanges.size() == 0) {
20738                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20739                        "*** Enqueueing dispatch uid changed!");
20740                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20741            }
20742            final int NA = mAvailUidChanges.size();
20743            if (NA > 0) {
20744                pendingChange = mAvailUidChanges.remove(NA-1);
20745                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20746                        "Retrieving available item: " + pendingChange);
20747            } else {
20748                pendingChange = new UidRecord.ChangeItem();
20749                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20750                        "Allocating new item: " + pendingChange);
20751            }
20752            if (uidRec != null) {
20753                uidRec.pendingChange = pendingChange;
20754                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20755                    // If this uid is going away, and we haven't yet reported it is gone,
20756                    // then do so now.
20757                    change = UidRecord.CHANGE_GONE_IDLE;
20758                }
20759            } else if (uid < 0) {
20760                throw new IllegalArgumentException("No UidRecord or uid");
20761            }
20762            pendingChange.uidRecord = uidRec;
20763            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20764            mPendingUidChanges.add(pendingChange);
20765        } else {
20766            pendingChange = uidRec.pendingChange;
20767            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20768                change = UidRecord.CHANGE_GONE_IDLE;
20769            }
20770        }
20771        pendingChange.change = change;
20772        pendingChange.processState = uidRec != null
20773                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20774    }
20775
20776    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20777            String authority) {
20778        if (app == null) return;
20779        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20780            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20781            if (userState == null) return;
20782            final long now = SystemClock.elapsedRealtime();
20783            Long lastReported = userState.mProviderLastReportedFg.get(authority);
20784            if (lastReported == null || lastReported < now - 60 * 1000L) {
20785                if (mSystemReady) {
20786                    // Cannot touch the user stats if not system ready
20787                    mUsageStatsService.reportContentProviderUsage(
20788                            authority, providerPkgName, app.userId);
20789                }
20790                userState.mProviderLastReportedFg.put(authority, now);
20791            }
20792        }
20793    }
20794
20795    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20796        if (DEBUG_USAGE_STATS) {
20797            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20798                    + "] state changes: old = " + app.setProcState + ", new = "
20799                    + app.curProcState);
20800        }
20801        if (mUsageStatsService == null) {
20802            return;
20803        }
20804        boolean isInteraction;
20805        // To avoid some abuse patterns, we are going to be careful about what we consider
20806        // to be an app interaction.  Being the top activity doesn't count while the display
20807        // is sleeping, nor do short foreground services.
20808        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20809            isInteraction = true;
20810            app.fgInteractionTime = 0;
20811        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20812            if (app.fgInteractionTime == 0) {
20813                app.fgInteractionTime = nowElapsed;
20814                isInteraction = false;
20815            } else {
20816                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20817            }
20818        } else {
20819            // If the app was being forced to the foreground, by say a Toast, then
20820            // no need to treat it as an interaction
20821            isInteraction = app.forcingToForeground == null
20822                    && app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20823            app.fgInteractionTime = 0;
20824        }
20825        if (isInteraction && (!app.reportedInteraction
20826                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20827            app.interactionEventTime = nowElapsed;
20828            String[] packages = app.getPackageList();
20829            if (packages != null) {
20830                for (int i = 0; i < packages.length; i++) {
20831                    mUsageStatsService.reportEvent(packages[i], app.userId,
20832                            UsageEvents.Event.SYSTEM_INTERACTION);
20833                }
20834            }
20835        }
20836        app.reportedInteraction = isInteraction;
20837        if (!isInteraction) {
20838            app.interactionEventTime = 0;
20839        }
20840    }
20841
20842    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20843        if (proc.thread != null) {
20844            if (proc.baseProcessTracker != null) {
20845                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20846            }
20847        }
20848    }
20849
20850    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20851            ProcessRecord TOP_APP, boolean doingAll, long now) {
20852        if (app.thread == null) {
20853            return false;
20854        }
20855
20856        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20857
20858        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20859    }
20860
20861    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20862            boolean oomAdj) {
20863        if (isForeground != proc.foregroundServices) {
20864            proc.foregroundServices = isForeground;
20865            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20866                    proc.info.uid);
20867            if (isForeground) {
20868                if (curProcs == null) {
20869                    curProcs = new ArrayList<ProcessRecord>();
20870                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20871                }
20872                if (!curProcs.contains(proc)) {
20873                    curProcs.add(proc);
20874                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20875                            proc.info.packageName, proc.info.uid);
20876                }
20877            } else {
20878                if (curProcs != null) {
20879                    if (curProcs.remove(proc)) {
20880                        mBatteryStatsService.noteEvent(
20881                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20882                                proc.info.packageName, proc.info.uid);
20883                        if (curProcs.size() <= 0) {
20884                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20885                        }
20886                    }
20887                }
20888            }
20889            if (oomAdj) {
20890                updateOomAdjLocked();
20891            }
20892        }
20893    }
20894
20895    private final ActivityRecord resumedAppLocked() {
20896        ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
20897        String pkg;
20898        int uid;
20899        if (act != null) {
20900            pkg = act.packageName;
20901            uid = act.info.applicationInfo.uid;
20902        } else {
20903            pkg = null;
20904            uid = -1;
20905        }
20906        // Has the UID or resumed package name changed?
20907        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20908                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20909            if (mCurResumedPackage != null) {
20910                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20911                        mCurResumedPackage, mCurResumedUid);
20912            }
20913            mCurResumedPackage = pkg;
20914            mCurResumedUid = uid;
20915            if (mCurResumedPackage != null) {
20916                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20917                        mCurResumedPackage, mCurResumedUid);
20918            }
20919        }
20920        return act;
20921    }
20922
20923    final boolean updateOomAdjLocked(ProcessRecord app) {
20924        final ActivityRecord TOP_ACT = resumedAppLocked();
20925        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20926        final boolean wasCached = app.cached;
20927
20928        mAdjSeq++;
20929
20930        // This is the desired cached adjusment we want to tell it to use.
20931        // If our app is currently cached, we know it, and that is it.  Otherwise,
20932        // we don't know it yet, and it needs to now be cached we will then
20933        // need to do a complete oom adj.
20934        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20935                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20936        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20937                SystemClock.uptimeMillis());
20938        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20939            // Changed to/from cached state, so apps after it in the LRU
20940            // list may also be changed.
20941            updateOomAdjLocked();
20942        }
20943        return success;
20944    }
20945
20946    final void updateOomAdjLocked() {
20947        final ActivityRecord TOP_ACT = resumedAppLocked();
20948        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20949        final long now = SystemClock.uptimeMillis();
20950        final long nowElapsed = SystemClock.elapsedRealtime();
20951        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20952        final int N = mLruProcesses.size();
20953
20954        if (false) {
20955            RuntimeException e = new RuntimeException();
20956            e.fillInStackTrace();
20957            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20958        }
20959
20960        // Reset state in all uid records.
20961        for (int i=mActiveUids.size()-1; i>=0; i--) {
20962            final UidRecord uidRec = mActiveUids.valueAt(i);
20963            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20964                    "Starting update of " + uidRec);
20965            uidRec.reset();
20966        }
20967
20968        mStackSupervisor.rankTaskLayersIfNeeded();
20969
20970        mAdjSeq++;
20971        mNewNumServiceProcs = 0;
20972        mNewNumAServiceProcs = 0;
20973
20974        final int emptyProcessLimit;
20975        final int cachedProcessLimit;
20976        if (mProcessLimit <= 0) {
20977            emptyProcessLimit = cachedProcessLimit = 0;
20978        } else if (mProcessLimit == 1) {
20979            emptyProcessLimit = 1;
20980            cachedProcessLimit = 0;
20981        } else {
20982            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20983            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20984        }
20985
20986        // Let's determine how many processes we have running vs.
20987        // how many slots we have for background processes; we may want
20988        // to put multiple processes in a slot of there are enough of
20989        // them.
20990        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20991                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20992        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20993        if (numEmptyProcs > cachedProcessLimit) {
20994            // If there are more empty processes than our limit on cached
20995            // processes, then use the cached process limit for the factor.
20996            // This ensures that the really old empty processes get pushed
20997            // down to the bottom, so if we are running low on memory we will
20998            // have a better chance at keeping around more cached processes
20999            // instead of a gazillion empty processes.
21000            numEmptyProcs = cachedProcessLimit;
21001        }
21002        int emptyFactor = numEmptyProcs/numSlots;
21003        if (emptyFactor < 1) emptyFactor = 1;
21004        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
21005        if (cachedFactor < 1) cachedFactor = 1;
21006        int stepCached = 0;
21007        int stepEmpty = 0;
21008        int numCached = 0;
21009        int numEmpty = 0;
21010        int numTrimming = 0;
21011
21012        mNumNonCachedProcs = 0;
21013        mNumCachedHiddenProcs = 0;
21014
21015        // First update the OOM adjustment for each of the
21016        // application processes based on their current state.
21017        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
21018        int nextCachedAdj = curCachedAdj+1;
21019        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
21020        int nextEmptyAdj = curEmptyAdj+2;
21021        for (int i=N-1; i>=0; i--) {
21022            ProcessRecord app = mLruProcesses.get(i);
21023            if (!app.killedByAm && app.thread != null) {
21024                app.procStateChanged = false;
21025                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
21026
21027                // If we haven't yet assigned the final cached adj
21028                // to the process, do that now.
21029                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
21030                    switch (app.curProcState) {
21031                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
21032                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
21033                            // This process is a cached process holding activities...
21034                            // assign it the next cached value for that type, and then
21035                            // step that cached level.
21036                            app.curRawAdj = curCachedAdj;
21037                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
21038                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
21039                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
21040                                    + ")");
21041                            if (curCachedAdj != nextCachedAdj) {
21042                                stepCached++;
21043                                if (stepCached >= cachedFactor) {
21044                                    stepCached = 0;
21045                                    curCachedAdj = nextCachedAdj;
21046                                    nextCachedAdj += 2;
21047                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
21048                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
21049                                    }
21050                                }
21051                            }
21052                            break;
21053                        default:
21054                            // For everything else, assign next empty cached process
21055                            // level and bump that up.  Note that this means that
21056                            // long-running services that have dropped down to the
21057                            // cached level will be treated as empty (since their process
21058                            // state is still as a service), which is what we want.
21059                            app.curRawAdj = curEmptyAdj;
21060                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
21061                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
21062                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
21063                                    + ")");
21064                            if (curEmptyAdj != nextEmptyAdj) {
21065                                stepEmpty++;
21066                                if (stepEmpty >= emptyFactor) {
21067                                    stepEmpty = 0;
21068                                    curEmptyAdj = nextEmptyAdj;
21069                                    nextEmptyAdj += 2;
21070                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
21071                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
21072                                    }
21073                                }
21074                            }
21075                            break;
21076                    }
21077                }
21078
21079                applyOomAdjLocked(app, true, now, nowElapsed);
21080
21081                // Count the number of process types.
21082                switch (app.curProcState) {
21083                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
21084                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
21085                        mNumCachedHiddenProcs++;
21086                        numCached++;
21087                        if (numCached > cachedProcessLimit) {
21088                            app.kill("cached #" + numCached, true);
21089                        }
21090                        break;
21091                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
21092                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
21093                                && app.lastActivityTime < oldTime) {
21094                            app.kill("empty for "
21095                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
21096                                    / 1000) + "s", true);
21097                        } else {
21098                            numEmpty++;
21099                            if (numEmpty > emptyProcessLimit) {
21100                                app.kill("empty #" + numEmpty, true);
21101                            }
21102                        }
21103                        break;
21104                    default:
21105                        mNumNonCachedProcs++;
21106                        break;
21107                }
21108
21109                if (app.isolated && app.services.size() <= 0) {
21110                    // If this is an isolated process, and there are no
21111                    // services running in it, then the process is no longer
21112                    // needed.  We agressively kill these because we can by
21113                    // definition not re-use the same process again, and it is
21114                    // good to avoid having whatever code was running in them
21115                    // left sitting around after no longer needed.
21116                    app.kill("isolated not needed", true);
21117                } else {
21118                    // Keeping this process, update its uid.
21119                    final UidRecord uidRec = app.uidRecord;
21120                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
21121                        uidRec.curProcState = app.curProcState;
21122                    }
21123                }
21124
21125                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21126                        && !app.killedByAm) {
21127                    numTrimming++;
21128                }
21129            }
21130        }
21131
21132        mNumServiceProcs = mNewNumServiceProcs;
21133
21134        // Now determine the memory trimming level of background processes.
21135        // Unfortunately we need to start at the back of the list to do this
21136        // properly.  We only do this if the number of background apps we
21137        // are managing to keep around is less than half the maximum we desire;
21138        // if we are keeping a good number around, we'll let them use whatever
21139        // memory they want.
21140        final int numCachedAndEmpty = numCached + numEmpty;
21141        int memFactor;
21142        if (numCached <= ProcessList.TRIM_CACHED_APPS
21143                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
21144            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
21145                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
21146            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
21147                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
21148            } else {
21149                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
21150            }
21151        } else {
21152            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
21153        }
21154        // We always allow the memory level to go up (better).  We only allow it to go
21155        // down if we are in a state where that is allowed, *and* the total number of processes
21156        // has gone down since last time.
21157        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
21158                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
21159                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
21160        if (memFactor > mLastMemoryLevel) {
21161            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
21162                memFactor = mLastMemoryLevel;
21163                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
21164            }
21165        }
21166        if (memFactor != mLastMemoryLevel) {
21167            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
21168        }
21169        mLastMemoryLevel = memFactor;
21170        mLastNumProcesses = mLruProcesses.size();
21171        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
21172        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
21173        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
21174            if (mLowRamStartTime == 0) {
21175                mLowRamStartTime = now;
21176            }
21177            int step = 0;
21178            int fgTrimLevel;
21179            switch (memFactor) {
21180                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
21181                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
21182                    break;
21183                case ProcessStats.ADJ_MEM_FACTOR_LOW:
21184                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
21185                    break;
21186                default:
21187                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
21188                    break;
21189            }
21190            int factor = numTrimming/3;
21191            int minFactor = 2;
21192            if (mHomeProcess != null) minFactor++;
21193            if (mPreviousProcess != null) minFactor++;
21194            if (factor < minFactor) factor = minFactor;
21195            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
21196            for (int i=N-1; i>=0; i--) {
21197                ProcessRecord app = mLruProcesses.get(i);
21198                if (allChanged || app.procStateChanged) {
21199                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
21200                    app.procStateChanged = false;
21201                }
21202                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21203                        && !app.killedByAm) {
21204                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
21205                        try {
21206                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21207                                    "Trimming memory of " + app.processName + " to " + curLevel);
21208                            app.thread.scheduleTrimMemory(curLevel);
21209                        } catch (RemoteException e) {
21210                        }
21211                        if (false) {
21212                            // For now we won't do this; our memory trimming seems
21213                            // to be good enough at this point that destroying
21214                            // activities causes more harm than good.
21215                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
21216                                    && app != mHomeProcess && app != mPreviousProcess) {
21217                                // Need to do this on its own message because the stack may not
21218                                // be in a consistent state at this point.
21219                                // For these apps we will also finish their activities
21220                                // to help them free memory.
21221                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
21222                            }
21223                        }
21224                    }
21225                    app.trimMemoryLevel = curLevel;
21226                    step++;
21227                    if (step >= factor) {
21228                        step = 0;
21229                        switch (curLevel) {
21230                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
21231                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
21232                                break;
21233                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
21234                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21235                                break;
21236                        }
21237                    }
21238                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21239                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
21240                            && app.thread != null) {
21241                        try {
21242                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21243                                    "Trimming memory of heavy-weight " + app.processName
21244                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21245                            app.thread.scheduleTrimMemory(
21246                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21247                        } catch (RemoteException e) {
21248                        }
21249                    }
21250                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21251                } else {
21252                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21253                            || app.systemNoUi) && app.pendingUiClean) {
21254                        // If this application is now in the background and it
21255                        // had done UI, then give it the special trim level to
21256                        // have it free UI resources.
21257                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
21258                        if (app.trimMemoryLevel < level && app.thread != null) {
21259                            try {
21260                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21261                                        "Trimming memory of bg-ui " + app.processName
21262                                        + " to " + level);
21263                                app.thread.scheduleTrimMemory(level);
21264                            } catch (RemoteException e) {
21265                            }
21266                        }
21267                        app.pendingUiClean = false;
21268                    }
21269                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
21270                        try {
21271                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21272                                    "Trimming memory of fg " + app.processName
21273                                    + " to " + fgTrimLevel);
21274                            app.thread.scheduleTrimMemory(fgTrimLevel);
21275                        } catch (RemoteException e) {
21276                        }
21277                    }
21278                    app.trimMemoryLevel = fgTrimLevel;
21279                }
21280            }
21281        } else {
21282            if (mLowRamStartTime != 0) {
21283                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
21284                mLowRamStartTime = 0;
21285            }
21286            for (int i=N-1; i>=0; i--) {
21287                ProcessRecord app = mLruProcesses.get(i);
21288                if (allChanged || app.procStateChanged) {
21289                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
21290                    app.procStateChanged = false;
21291                }
21292                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21293                        || app.systemNoUi) && app.pendingUiClean) {
21294                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
21295                            && app.thread != null) {
21296                        try {
21297                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21298                                    "Trimming memory of ui hidden " + app.processName
21299                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21300                            app.thread.scheduleTrimMemory(
21301                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21302                        } catch (RemoteException e) {
21303                        }
21304                    }
21305                    app.pendingUiClean = false;
21306                }
21307                app.trimMemoryLevel = 0;
21308            }
21309        }
21310
21311        if (mAlwaysFinishActivities) {
21312            // Need to do this on its own message because the stack may not
21313            // be in a consistent state at this point.
21314            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
21315        }
21316
21317        if (allChanged) {
21318            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
21319        }
21320
21321        // Update from any uid changes.
21322        for (int i=mActiveUids.size()-1; i>=0; i--) {
21323            final UidRecord uidRec = mActiveUids.valueAt(i);
21324            int uidChange = UidRecord.CHANGE_PROCSTATE;
21325            if (uidRec.setProcState != uidRec.curProcState) {
21326                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21327                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
21328                        + " to " + uidRec.curProcState);
21329                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
21330                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
21331                        uidRec.lastBackgroundTime = nowElapsed;
21332                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
21333                            // Note: the background settle time is in elapsed realtime, while
21334                            // the handler time base is uptime.  All this means is that we may
21335                            // stop background uids later than we had intended, but that only
21336                            // happens because the device was sleeping so we are okay anyway.
21337                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
21338                        }
21339                    }
21340                } else {
21341                    if (uidRec.idle) {
21342                        uidChange = UidRecord.CHANGE_ACTIVE;
21343                        uidRec.idle = false;
21344                    }
21345                    uidRec.lastBackgroundTime = 0;
21346                }
21347                uidRec.setProcState = uidRec.curProcState;
21348                enqueueUidChangeLocked(uidRec, -1, uidChange);
21349                noteUidProcessState(uidRec.uid, uidRec.curProcState);
21350            }
21351        }
21352
21353        if (mProcessStats.shouldWriteNowLocked(now)) {
21354            mHandler.post(new Runnable() {
21355                @Override public void run() {
21356                    synchronized (ActivityManagerService.this) {
21357                        mProcessStats.writeStateAsyncLocked();
21358                    }
21359                }
21360            });
21361        }
21362
21363        if (DEBUG_OOM_ADJ) {
21364            final long duration = SystemClock.uptimeMillis() - now;
21365            if (false) {
21366                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
21367                        new RuntimeException("here").fillInStackTrace());
21368            } else {
21369                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
21370            }
21371        }
21372    }
21373
21374    final void idleUids() {
21375        synchronized (this) {
21376            final long nowElapsed = SystemClock.elapsedRealtime();
21377            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
21378            long nextTime = 0;
21379            for (int i=mActiveUids.size()-1; i>=0; i--) {
21380                final UidRecord uidRec = mActiveUids.valueAt(i);
21381                final long bgTime = uidRec.lastBackgroundTime;
21382                if (bgTime > 0 && !uidRec.idle) {
21383                    if (bgTime <= maxBgTime) {
21384                        uidRec.idle = true;
21385                        doStopUidLocked(uidRec.uid, uidRec);
21386                    } else {
21387                        if (nextTime == 0 || nextTime > bgTime) {
21388                            nextTime = bgTime;
21389                        }
21390                    }
21391                }
21392            }
21393            if (nextTime > 0) {
21394                mHandler.removeMessages(IDLE_UIDS_MSG);
21395                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
21396                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
21397            }
21398        }
21399    }
21400
21401    final void runInBackgroundDisabled(int uid) {
21402        synchronized (this) {
21403            UidRecord uidRec = mActiveUids.get(uid);
21404            if (uidRec != null) {
21405                // This uid is actually running...  should it be considered background now?
21406                if (uidRec.idle) {
21407                    doStopUidLocked(uidRec.uid, uidRec);
21408                }
21409            } else {
21410                // This uid isn't actually running...  still send a report about it being "stopped".
21411                doStopUidLocked(uid, null);
21412            }
21413        }
21414    }
21415
21416    final void doStopUidLocked(int uid, final UidRecord uidRec) {
21417        mServices.stopInBackgroundLocked(uid);
21418        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
21419    }
21420
21421    final void trimApplications() {
21422        synchronized (this) {
21423            int i;
21424
21425            // First remove any unused application processes whose package
21426            // has been removed.
21427            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
21428                final ProcessRecord app = mRemovedProcesses.get(i);
21429                if (app.activities.size() == 0
21430                        && app.curReceivers.isEmpty() && app.services.size() == 0) {
21431                    Slog.i(
21432                        TAG, "Exiting empty application process "
21433                        + app.toShortString() + " ("
21434                        + (app.thread != null ? app.thread.asBinder() : null)
21435                        + ")\n");
21436                    if (app.pid > 0 && app.pid != MY_PID) {
21437                        app.kill("empty", false);
21438                    } else {
21439                        try {
21440                            app.thread.scheduleExit();
21441                        } catch (Exception e) {
21442                            // Ignore exceptions.
21443                        }
21444                    }
21445                    cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
21446                    mRemovedProcesses.remove(i);
21447
21448                    if (app.persistent) {
21449                        addAppLocked(app.info, false, null /* ABI override */);
21450                    }
21451                }
21452            }
21453
21454            // Now update the oom adj for all processes.
21455            updateOomAdjLocked();
21456        }
21457    }
21458
21459    /** This method sends the specified signal to each of the persistent apps */
21460    public void signalPersistentProcesses(int sig) throws RemoteException {
21461        if (sig != Process.SIGNAL_USR1) {
21462            throw new SecurityException("Only SIGNAL_USR1 is allowed");
21463        }
21464
21465        synchronized (this) {
21466            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
21467                    != PackageManager.PERMISSION_GRANTED) {
21468                throw new SecurityException("Requires permission "
21469                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
21470            }
21471
21472            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
21473                ProcessRecord r = mLruProcesses.get(i);
21474                if (r.thread != null && r.persistent) {
21475                    Process.sendSignal(r.pid, sig);
21476                }
21477            }
21478        }
21479    }
21480
21481    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
21482        if (proc == null || proc == mProfileProc) {
21483            proc = mProfileProc;
21484            profileType = mProfileType;
21485            clearProfilerLocked();
21486        }
21487        if (proc == null) {
21488            return;
21489        }
21490        try {
21491            proc.thread.profilerControl(false, null, profileType);
21492        } catch (RemoteException e) {
21493            throw new IllegalStateException("Process disappeared");
21494        }
21495    }
21496
21497    private void clearProfilerLocked() {
21498        if (mProfileFd != null) {
21499            try {
21500                mProfileFd.close();
21501            } catch (IOException e) {
21502            }
21503        }
21504        mProfileApp = null;
21505        mProfileProc = null;
21506        mProfileFile = null;
21507        mProfileType = 0;
21508        mAutoStopProfiler = false;
21509        mSamplingInterval = 0;
21510    }
21511
21512    public boolean profileControl(String process, int userId, boolean start,
21513            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
21514
21515        try {
21516            synchronized (this) {
21517                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21518                // its own permission.
21519                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21520                        != PackageManager.PERMISSION_GRANTED) {
21521                    throw new SecurityException("Requires permission "
21522                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21523                }
21524
21525                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
21526                    throw new IllegalArgumentException("null profile info or fd");
21527                }
21528
21529                ProcessRecord proc = null;
21530                if (process != null) {
21531                    proc = findProcessLocked(process, userId, "profileControl");
21532                }
21533
21534                if (start && (proc == null || proc.thread == null)) {
21535                    throw new IllegalArgumentException("Unknown process: " + process);
21536                }
21537
21538                if (start) {
21539                    stopProfilerLocked(null, 0);
21540                    setProfileApp(proc.info, proc.processName, profilerInfo);
21541                    mProfileProc = proc;
21542                    mProfileType = profileType;
21543                    ParcelFileDescriptor fd = profilerInfo.profileFd;
21544                    try {
21545                        fd = fd.dup();
21546                    } catch (IOException e) {
21547                        fd = null;
21548                    }
21549                    profilerInfo.profileFd = fd;
21550                    proc.thread.profilerControl(start, profilerInfo, profileType);
21551                    fd = null;
21552                    mProfileFd = null;
21553                } else {
21554                    stopProfilerLocked(proc, profileType);
21555                    if (profilerInfo != null && profilerInfo.profileFd != null) {
21556                        try {
21557                            profilerInfo.profileFd.close();
21558                        } catch (IOException e) {
21559                        }
21560                    }
21561                }
21562
21563                return true;
21564            }
21565        } catch (RemoteException e) {
21566            throw new IllegalStateException("Process disappeared");
21567        } finally {
21568            if (profilerInfo != null && profilerInfo.profileFd != null) {
21569                try {
21570                    profilerInfo.profileFd.close();
21571                } catch (IOException e) {
21572                }
21573            }
21574        }
21575    }
21576
21577    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
21578        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21579                userId, true, ALLOW_FULL_ONLY, callName, null);
21580        ProcessRecord proc = null;
21581        try {
21582            int pid = Integer.parseInt(process);
21583            synchronized (mPidsSelfLocked) {
21584                proc = mPidsSelfLocked.get(pid);
21585            }
21586        } catch (NumberFormatException e) {
21587        }
21588
21589        if (proc == null) {
21590            ArrayMap<String, SparseArray<ProcessRecord>> all
21591                    = mProcessNames.getMap();
21592            SparseArray<ProcessRecord> procs = all.get(process);
21593            if (procs != null && procs.size() > 0) {
21594                proc = procs.valueAt(0);
21595                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
21596                    for (int i=1; i<procs.size(); i++) {
21597                        ProcessRecord thisProc = procs.valueAt(i);
21598                        if (thisProc.userId == userId) {
21599                            proc = thisProc;
21600                            break;
21601                        }
21602                    }
21603                }
21604            }
21605        }
21606
21607        return proc;
21608    }
21609
21610    public boolean dumpHeap(String process, int userId, boolean managed,
21611            String path, ParcelFileDescriptor fd) throws RemoteException {
21612
21613        try {
21614            synchronized (this) {
21615                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21616                // its own permission (same as profileControl).
21617                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21618                        != PackageManager.PERMISSION_GRANTED) {
21619                    throw new SecurityException("Requires permission "
21620                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21621                }
21622
21623                if (fd == null) {
21624                    throw new IllegalArgumentException("null fd");
21625                }
21626
21627                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
21628                if (proc == null || proc.thread == null) {
21629                    throw new IllegalArgumentException("Unknown process: " + process);
21630                }
21631
21632                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21633                if (!isDebuggable) {
21634                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21635                        throw new SecurityException("Process not debuggable: " + proc);
21636                    }
21637                }
21638
21639                proc.thread.dumpHeap(managed, path, fd);
21640                fd = null;
21641                return true;
21642            }
21643        } catch (RemoteException e) {
21644            throw new IllegalStateException("Process disappeared");
21645        } finally {
21646            if (fd != null) {
21647                try {
21648                    fd.close();
21649                } catch (IOException e) {
21650                }
21651            }
21652        }
21653    }
21654
21655    @Override
21656    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
21657            String reportPackage) {
21658        if (processName != null) {
21659            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
21660                    "setDumpHeapDebugLimit()");
21661        } else {
21662            synchronized (mPidsSelfLocked) {
21663                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
21664                if (proc == null) {
21665                    throw new SecurityException("No process found for calling pid "
21666                            + Binder.getCallingPid());
21667                }
21668                if (!Build.IS_DEBUGGABLE
21669                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21670                    throw new SecurityException("Not running a debuggable build");
21671                }
21672                processName = proc.processName;
21673                uid = proc.uid;
21674                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
21675                    throw new SecurityException("Package " + reportPackage + " is not running in "
21676                            + proc);
21677                }
21678            }
21679        }
21680        synchronized (this) {
21681            if (maxMemSize > 0) {
21682                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
21683            } else {
21684                if (uid != 0) {
21685                    mMemWatchProcesses.remove(processName, uid);
21686                } else {
21687                    mMemWatchProcesses.getMap().remove(processName);
21688                }
21689            }
21690        }
21691    }
21692
21693    @Override
21694    public void dumpHeapFinished(String path) {
21695        synchronized (this) {
21696            if (Binder.getCallingPid() != mMemWatchDumpPid) {
21697                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
21698                        + " does not match last pid " + mMemWatchDumpPid);
21699                return;
21700            }
21701            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
21702                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
21703                        + " does not match last path " + mMemWatchDumpFile);
21704                return;
21705            }
21706            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21707            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21708        }
21709    }
21710
21711    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21712    public void monitor() {
21713        synchronized (this) { }
21714    }
21715
21716    void onCoreSettingsChange(Bundle settings) {
21717        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21718            ProcessRecord processRecord = mLruProcesses.get(i);
21719            try {
21720                if (processRecord.thread != null) {
21721                    processRecord.thread.setCoreSettings(settings);
21722                }
21723            } catch (RemoteException re) {
21724                /* ignore */
21725            }
21726        }
21727    }
21728
21729    // Multi-user methods
21730
21731    /**
21732     * Start user, if its not already running, but don't bring it to foreground.
21733     */
21734    @Override
21735    public boolean startUserInBackground(final int userId) {
21736        return mUserController.startUser(userId, /* foreground */ false);
21737    }
21738
21739    @Override
21740    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21741        return mUserController.unlockUser(userId, token, secret, listener);
21742    }
21743
21744    @Override
21745    public boolean switchUser(final int targetUserId) {
21746        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21747        int currentUserId;
21748        UserInfo targetUserInfo;
21749        synchronized (this) {
21750            currentUserId = mUserController.getCurrentUserIdLocked();
21751            targetUserInfo = mUserController.getUserInfo(targetUserId);
21752            if (targetUserId == currentUserId) {
21753                Slog.i(TAG, "user #" + targetUserId + " is already the current user");
21754                return true;
21755            }
21756            if (targetUserInfo == null) {
21757                Slog.w(TAG, "No user info for user #" + targetUserId);
21758                return false;
21759            }
21760            if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
21761                Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
21762                        + " when device is in demo mode");
21763                return false;
21764            }
21765            if (!targetUserInfo.supportsSwitchTo()) {
21766                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21767                return false;
21768            }
21769            if (targetUserInfo.isManagedProfile()) {
21770                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21771                return false;
21772            }
21773            mUserController.setTargetUserIdLocked(targetUserId);
21774        }
21775        if (mUserController.mUserSwitchUiEnabled) {
21776            UserInfo currentUserInfo = mUserController.getUserInfo(currentUserId);
21777            Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21778            mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21779            mUiHandler.sendMessage(mHandler.obtainMessage(
21780                    START_USER_SWITCH_UI_MSG, userNames));
21781        } else {
21782            mHandler.removeMessages(START_USER_SWITCH_FG_MSG);
21783            mHandler.sendMessage(mHandler.obtainMessage(
21784                    START_USER_SWITCH_FG_MSG, targetUserId, 0));
21785        }
21786        return true;
21787    }
21788
21789    void scheduleStartProfilesLocked() {
21790        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21791            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21792                    DateUtils.SECOND_IN_MILLIS);
21793        }
21794    }
21795
21796    @Override
21797    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21798        return mUserController.stopUser(userId, force, callback);
21799    }
21800
21801    @Override
21802    public UserInfo getCurrentUser() {
21803        return mUserController.getCurrentUser();
21804    }
21805
21806    String getStartedUserState(int userId) {
21807        synchronized (this) {
21808            final UserState userState = mUserController.getStartedUserStateLocked(userId);
21809            return UserState.stateToString(userState.state);
21810        }
21811    }
21812
21813    @Override
21814    public boolean isUserRunning(int userId, int flags) {
21815        if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
21816                && checkCallingPermission(INTERACT_ACROSS_USERS)
21817                    != PackageManager.PERMISSION_GRANTED) {
21818            String msg = "Permission Denial: isUserRunning() from pid="
21819                    + Binder.getCallingPid()
21820                    + ", uid=" + Binder.getCallingUid()
21821                    + " requires " + INTERACT_ACROSS_USERS;
21822            Slog.w(TAG, msg);
21823            throw new SecurityException(msg);
21824        }
21825        synchronized (this) {
21826            return mUserController.isUserRunningLocked(userId, flags);
21827        }
21828    }
21829
21830    @Override
21831    public int[] getRunningUserIds() {
21832        if (checkCallingPermission(INTERACT_ACROSS_USERS)
21833                != PackageManager.PERMISSION_GRANTED) {
21834            String msg = "Permission Denial: isUserRunning() from pid="
21835                    + Binder.getCallingPid()
21836                    + ", uid=" + Binder.getCallingUid()
21837                    + " requires " + INTERACT_ACROSS_USERS;
21838            Slog.w(TAG, msg);
21839            throw new SecurityException(msg);
21840        }
21841        synchronized (this) {
21842            return mUserController.getStartedUserArrayLocked();
21843        }
21844    }
21845
21846    @Override
21847    public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
21848        mUserController.registerUserSwitchObserver(observer, name);
21849    }
21850
21851    @Override
21852    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21853        mUserController.unregisterUserSwitchObserver(observer);
21854    }
21855
21856    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21857        if (info == null) return null;
21858        ApplicationInfo newInfo = new ApplicationInfo(info);
21859        newInfo.initForUser(userId);
21860        return newInfo;
21861    }
21862
21863    public boolean isUserStopped(int userId) {
21864        synchronized (this) {
21865            return mUserController.getStartedUserStateLocked(userId) == null;
21866        }
21867    }
21868
21869    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21870        if (aInfo == null
21871                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21872            return aInfo;
21873        }
21874
21875        ActivityInfo info = new ActivityInfo(aInfo);
21876        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21877        return info;
21878    }
21879
21880    private boolean processSanityChecksLocked(ProcessRecord process) {
21881        if (process == null || process.thread == null) {
21882            return false;
21883        }
21884
21885        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21886        if (!isDebuggable) {
21887            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21888                return false;
21889            }
21890        }
21891
21892        return true;
21893    }
21894
21895    public boolean startBinderTracking() throws RemoteException {
21896        synchronized (this) {
21897            mBinderTransactionTrackingEnabled = true;
21898            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21899            // permission (same as profileControl).
21900            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21901                    != PackageManager.PERMISSION_GRANTED) {
21902                throw new SecurityException("Requires permission "
21903                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21904            }
21905
21906            for (int i = 0; i < mLruProcesses.size(); i++) {
21907                ProcessRecord process = mLruProcesses.get(i);
21908                if (!processSanityChecksLocked(process)) {
21909                    continue;
21910                }
21911                try {
21912                    process.thread.startBinderTracking();
21913                } catch (RemoteException e) {
21914                    Log.v(TAG, "Process disappared");
21915                }
21916            }
21917            return true;
21918        }
21919    }
21920
21921    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21922        try {
21923            synchronized (this) {
21924                mBinderTransactionTrackingEnabled = false;
21925                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21926                // permission (same as profileControl).
21927                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21928                        != PackageManager.PERMISSION_GRANTED) {
21929                    throw new SecurityException("Requires permission "
21930                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21931                }
21932
21933                if (fd == null) {
21934                    throw new IllegalArgumentException("null fd");
21935                }
21936
21937                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21938                pw.println("Binder transaction traces for all processes.\n");
21939                for (ProcessRecord process : mLruProcesses) {
21940                    if (!processSanityChecksLocked(process)) {
21941                        continue;
21942                    }
21943
21944                    pw.println("Traces for process: " + process.processName);
21945                    pw.flush();
21946                    try {
21947                        TransferPipe tp = new TransferPipe();
21948                        try {
21949                            process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
21950                            tp.go(fd.getFileDescriptor());
21951                        } finally {
21952                            tp.kill();
21953                        }
21954                    } catch (IOException e) {
21955                        pw.println("Failure while dumping IPC traces from " + process +
21956                                ".  Exception: " + e);
21957                        pw.flush();
21958                    } catch (RemoteException e) {
21959                        pw.println("Got a RemoteException while dumping IPC traces from " +
21960                                process + ".  Exception: " + e);
21961                        pw.flush();
21962                    }
21963                }
21964                fd = null;
21965                return true;
21966            }
21967        } finally {
21968            if (fd != null) {
21969                try {
21970                    fd.close();
21971                } catch (IOException e) {
21972                }
21973            }
21974        }
21975    }
21976
21977    private final class LocalService extends ActivityManagerInternal {
21978        @Override
21979        public void onWakefulnessChanged(int wakefulness) {
21980            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21981        }
21982
21983        @Override
21984        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21985                String processName, String abiOverride, int uid, Runnable crashHandler) {
21986            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21987                    processName, abiOverride, uid, crashHandler);
21988        }
21989
21990        @Override
21991        public SleepToken acquireSleepToken(String tag) {
21992            Preconditions.checkNotNull(tag);
21993
21994            ComponentName requestedVrService = null;
21995            ComponentName callingVrActivity = null;
21996            int userId = -1;
21997            synchronized (ActivityManagerService.this) {
21998                final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
21999                if (resumedActivity != null) {
22000                    requestedVrService = resumedActivity.requestedVrComponent;
22001                    callingVrActivity = resumedActivity.info.getComponentName();
22002                    userId = resumedActivity.userId;
22003                }
22004            }
22005
22006            if (requestedVrService != null) {
22007                applyVrMode(false, requestedVrService, userId, callingVrActivity, true);
22008            }
22009
22010            synchronized (ActivityManagerService.this) {
22011                SleepTokenImpl token = new SleepTokenImpl(tag);
22012                mSleepTokens.add(token);
22013                updateSleepIfNeededLocked();
22014                return token;
22015            }
22016        }
22017
22018        @Override
22019        public ComponentName getHomeActivityForUser(int userId) {
22020            synchronized (ActivityManagerService.this) {
22021                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
22022                return homeActivity == null ? null : homeActivity.realActivity;
22023            }
22024        }
22025
22026        @Override
22027        public void onUserRemoved(int userId) {
22028            synchronized (ActivityManagerService.this) {
22029                ActivityManagerService.this.onUserStoppedLocked(userId);
22030            }
22031        }
22032
22033        @Override
22034        public void onLocalVoiceInteractionStarted(IBinder activity,
22035                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
22036            synchronized (ActivityManagerService.this) {
22037                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
22038                        voiceSession, voiceInteractor);
22039            }
22040        }
22041
22042        @Override
22043        public void notifyStartingWindowDrawn() {
22044            synchronized (ActivityManagerService.this) {
22045                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
22046            }
22047        }
22048
22049        @Override
22050        public void notifyAppTransitionStarting(int reason) {
22051            synchronized (ActivityManagerService.this) {
22052                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
22053            }
22054        }
22055
22056        @Override
22057        public void notifyAppTransitionFinished() {
22058            synchronized (ActivityManagerService.this) {
22059                mStackSupervisor.notifyAppTransitionDone();
22060            }
22061        }
22062
22063        @Override
22064        public void notifyAppTransitionCancelled() {
22065            synchronized (ActivityManagerService.this) {
22066                mStackSupervisor.notifyAppTransitionDone();
22067            }
22068        }
22069
22070        @Override
22071        public List<IBinder> getTopVisibleActivities() {
22072            synchronized (ActivityManagerService.this) {
22073                return mStackSupervisor.getTopVisibleActivities();
22074            }
22075        }
22076
22077        @Override
22078        public void notifyDockedStackMinimizedChanged(boolean minimized) {
22079            synchronized (ActivityManagerService.this) {
22080                mStackSupervisor.setDockedStackMinimized(minimized);
22081            }
22082        }
22083
22084        @Override
22085        public void killForegroundAppsForUser(int userHandle) {
22086            synchronized (ActivityManagerService.this) {
22087                final ArrayList<ProcessRecord> procs = new ArrayList<>();
22088                final int NP = mProcessNames.getMap().size();
22089                for (int ip = 0; ip < NP; ip++) {
22090                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
22091                    final int NA = apps.size();
22092                    for (int ia = 0; ia < NA; ia++) {
22093                        final ProcessRecord app = apps.valueAt(ia);
22094                        if (app.persistent) {
22095                            // We don't kill persistent processes.
22096                            continue;
22097                        }
22098                        if (app.removed) {
22099                            procs.add(app);
22100                        } else if (app.userId == userHandle && app.foregroundActivities) {
22101                            app.removed = true;
22102                            procs.add(app);
22103                        }
22104                    }
22105                }
22106
22107                final int N = procs.size();
22108                for (int i = 0; i < N; i++) {
22109                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
22110                }
22111            }
22112        }
22113
22114        @Override
22115        public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
22116            if (!(target instanceof PendingIntentRecord)) {
22117                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
22118                return;
22119            }
22120            ((PendingIntentRecord) target).setWhitelistDuration(duration);
22121        }
22122
22123        @Override
22124        public void updatePersistentConfigurationForUser(@NonNull Configuration values,
22125                int userId) {
22126            Preconditions.checkNotNull(values, "Configuration must not be null");
22127            Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
22128            synchronized (ActivityManagerService.this) {
22129                updateConfigurationLocked(values, null, false, true, userId,
22130                        false /* deferResume */);
22131            }
22132        }
22133
22134        @Override
22135        public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
22136                Bundle bOptions) {
22137            Preconditions.checkNotNull(intents, "intents");
22138            final String[] resolvedTypes = new String[intents.length];
22139            for (int i = 0; i < intents.length; i++) {
22140                resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
22141            }
22142
22143            // UID of the package on user userId.
22144            // "= 0" is needed because otherwise catch(RemoteException) would make it look like
22145            // packageUid may not be initialized.
22146            int packageUid = 0;
22147            try {
22148                packageUid = AppGlobals.getPackageManager().getPackageUid(
22149                        packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
22150            } catch (RemoteException e) {
22151                // Shouldn't happen.
22152            }
22153
22154            synchronized (ActivityManagerService.this) {
22155                return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
22156                        /*resultTo*/ null, bOptions, userId);
22157            }
22158        }
22159
22160        @Override
22161        public int getUidProcessState(int uid) {
22162            return getUidState(uid);
22163        }
22164    }
22165
22166    private final class SleepTokenImpl extends SleepToken {
22167        private final String mTag;
22168        private final long mAcquireTime;
22169
22170        public SleepTokenImpl(String tag) {
22171            mTag = tag;
22172            mAcquireTime = SystemClock.uptimeMillis();
22173        }
22174
22175        @Override
22176        public void release() {
22177            synchronized (ActivityManagerService.this) {
22178                if (mSleepTokens.remove(this)) {
22179                    updateSleepIfNeededLocked();
22180                }
22181            }
22182        }
22183
22184        @Override
22185        public String toString() {
22186            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
22187        }
22188    }
22189
22190    /**
22191     * An implementation of IAppTask, that allows an app to manage its own tasks via
22192     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
22193     * only the process that calls getAppTasks() can call the AppTask methods.
22194     */
22195    class AppTaskImpl extends IAppTask.Stub {
22196        private int mTaskId;
22197        private int mCallingUid;
22198
22199        public AppTaskImpl(int taskId, int callingUid) {
22200            mTaskId = taskId;
22201            mCallingUid = callingUid;
22202        }
22203
22204        private void checkCaller() {
22205            if (mCallingUid != Binder.getCallingUid()) {
22206                throw new SecurityException("Caller " + mCallingUid
22207                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
22208            }
22209        }
22210
22211        @Override
22212        public void finishAndRemoveTask() {
22213            checkCaller();
22214
22215            synchronized (ActivityManagerService.this) {
22216                long origId = Binder.clearCallingIdentity();
22217                try {
22218                    // We remove the task from recents to preserve backwards
22219                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
22220                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22221                    }
22222                } finally {
22223                    Binder.restoreCallingIdentity(origId);
22224                }
22225            }
22226        }
22227
22228        @Override
22229        public ActivityManager.RecentTaskInfo getTaskInfo() {
22230            checkCaller();
22231
22232            synchronized (ActivityManagerService.this) {
22233                long origId = Binder.clearCallingIdentity();
22234                try {
22235                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22236                    if (tr == null) {
22237                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22238                    }
22239                    return createRecentTaskInfoFromTaskRecord(tr);
22240                } finally {
22241                    Binder.restoreCallingIdentity(origId);
22242                }
22243            }
22244        }
22245
22246        @Override
22247        public void moveToFront() {
22248            checkCaller();
22249            // Will bring task to front if it already has a root activity.
22250            final long origId = Binder.clearCallingIdentity();
22251            try {
22252                synchronized (this) {
22253                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
22254                }
22255            } finally {
22256                Binder.restoreCallingIdentity(origId);
22257            }
22258        }
22259
22260        @Override
22261        public int startActivity(IBinder whoThread, String callingPackage,
22262                Intent intent, String resolvedType, Bundle bOptions) {
22263            checkCaller();
22264
22265            int callingUser = UserHandle.getCallingUserId();
22266            TaskRecord tr;
22267            IApplicationThread appThread;
22268            synchronized (ActivityManagerService.this) {
22269                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22270                if (tr == null) {
22271                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22272                }
22273                appThread = IApplicationThread.Stub.asInterface(whoThread);
22274                if (appThread == null) {
22275                    throw new IllegalArgumentException("Bad app thread " + appThread);
22276                }
22277            }
22278            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
22279                    resolvedType, null, null, null, null, 0, 0, null, null,
22280                    null, bOptions, false, callingUser, null, tr);
22281        }
22282
22283        @Override
22284        public void setExcludeFromRecents(boolean exclude) {
22285            checkCaller();
22286
22287            synchronized (ActivityManagerService.this) {
22288                long origId = Binder.clearCallingIdentity();
22289                try {
22290                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22291                    if (tr == null) {
22292                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22293                    }
22294                    Intent intent = tr.getBaseIntent();
22295                    if (exclude) {
22296                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22297                    } else {
22298                        intent.setFlags(intent.getFlags()
22299                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22300                    }
22301                } finally {
22302                    Binder.restoreCallingIdentity(origId);
22303                }
22304            }
22305        }
22306    }
22307
22308    /**
22309     * Kill processes for the user with id userId and that depend on the package named packageName
22310     */
22311    @Override
22312    public void killPackageDependents(String packageName, int userId) {
22313        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
22314        if (packageName == null) {
22315            throw new NullPointerException(
22316                    "Cannot kill the dependents of a package without its name.");
22317        }
22318
22319        long callingId = Binder.clearCallingIdentity();
22320        IPackageManager pm = AppGlobals.getPackageManager();
22321        int pkgUid = -1;
22322        try {
22323            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
22324        } catch (RemoteException e) {
22325        }
22326        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
22327            throw new IllegalArgumentException(
22328                    "Cannot kill dependents of non-existing package " + packageName);
22329        }
22330        try {
22331            synchronized(this) {
22332                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
22333                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
22334                        "dep: " + packageName);
22335            }
22336        } finally {
22337            Binder.restoreCallingIdentity(callingId);
22338        }
22339    }
22340
22341    @Override
22342    public boolean canBypassWorkChallenge(PendingIntent intent) throws RemoteException {
22343        final int userId = intent.getCreatorUserHandle().getIdentifier();
22344        if (!mUserController.isUserRunningLocked(userId, ActivityManager.FLAG_AND_LOCKED)) {
22345            return false;
22346        }
22347        IIntentSender target = intent.getTarget();
22348        if (!(target instanceof PendingIntentRecord)) {
22349            return false;
22350        }
22351        final PendingIntentRecord record = (PendingIntentRecord) target;
22352        final ResolveInfo rInfo = mStackSupervisor.resolveIntent(record.key.requestIntent,
22353                record.key.requestResolvedType, userId, PackageManager.MATCH_DIRECT_BOOT_AWARE);
22354        // For direct boot aware activities, they can be shown without triggering a work challenge
22355        // before the profile user is unlocked.
22356        return rInfo != null && rInfo.activityInfo != null;
22357    }
22358
22359    /**
22360     * Attach an agent to the specified process (proces name or PID)
22361     */
22362    public void attachAgent(String process, String path) {
22363        try {
22364            synchronized (this) {
22365                ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
22366                if (proc == null || proc.thread == null) {
22367                    throw new IllegalArgumentException("Unknown process: " + process);
22368                }
22369
22370                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
22371                if (!isDebuggable) {
22372                    if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
22373                        throw new SecurityException("Process not debuggable: " + proc);
22374                    }
22375                }
22376
22377                proc.thread.attachAgent(path);
22378            }
22379        } catch (RemoteException e) {
22380            throw new IllegalStateException("Process disappeared");
22381        }
22382    }
22383}
22384