ActivityManagerService.java revision 1779e6108ab264689b7d5e5c42ba3cbca6c8189f
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.os.IDeviceIdentifiersPolicyService;
20import com.android.internal.telephony.TelephonyIntents;
21import com.google.android.collect.Lists;
22import com.google.android.collect.Maps;
23import com.android.internal.R;
24import com.android.internal.annotations.GuardedBy;
25import com.android.internal.app.AssistUtils;
26import com.android.internal.app.DumpHeapActivity;
27import com.android.internal.app.IAppOpsCallback;
28import com.android.internal.app.IAppOpsService;
29import com.android.internal.app.IVoiceInteractor;
30import com.android.internal.app.ProcessMap;
31import com.android.internal.app.SystemUserHomeActivity;
32import com.android.internal.app.procstats.ProcessStats;
33import com.android.internal.os.BackgroundThread;
34import com.android.internal.os.BatteryStatsImpl;
35import com.android.internal.os.IResultReceiver;
36import com.android.internal.os.ProcessCpuTracker;
37import com.android.internal.os.TransferPipe;
38import com.android.internal.os.Zygote;
39import com.android.internal.os.InstallerConnection.InstallerException;
40import com.android.internal.util.ArrayUtils;
41import com.android.internal.util.FastPrintWriter;
42import com.android.internal.util.FastXmlSerializer;
43import com.android.internal.util.MemInfoReader;
44import com.android.internal.util.Preconditions;
45import com.android.server.AppOpsService;
46import com.android.server.AttributeCache;
47import com.android.server.DeviceIdleController;
48import com.android.server.IntentResolver;
49import com.android.server.LocalServices;
50import com.android.server.LockGuard;
51import com.android.server.ServiceThread;
52import com.android.server.SystemService;
53import com.android.server.SystemServiceManager;
54import com.android.server.Watchdog;
55import com.android.server.am.ActivityStack.ActivityState;
56import com.android.server.firewall.IntentFirewall;
57import com.android.server.pm.Installer;
58import com.android.server.statusbar.StatusBarManagerInternal;
59import com.android.server.vr.VrManagerInternal;
60import com.android.server.wm.WindowManagerService;
61
62import org.xmlpull.v1.XmlPullParser;
63import org.xmlpull.v1.XmlPullParserException;
64import org.xmlpull.v1.XmlSerializer;
65
66import android.Manifest;
67import android.Manifest.permission;
68import android.annotation.NonNull;
69import android.annotation.UserIdInt;
70import android.app.Activity;
71import android.app.ActivityManager;
72import android.app.ActivityManager.RunningTaskInfo;
73import android.app.ActivityManager.StackId;
74import android.app.ActivityManager.StackInfo;
75import android.app.ActivityManager.TaskThumbnailInfo;
76import android.app.ActivityManagerInternal;
77import android.app.ActivityManagerInternal.SleepToken;
78import android.app.ActivityManagerNative;
79import android.app.ActivityOptions;
80import android.app.ActivityThread;
81import android.app.AlertDialog;
82import android.app.AppGlobals;
83import android.app.AppOpsManager;
84import android.app.ApplicationErrorReport;
85import android.app.ApplicationThreadNative;
86import android.app.BroadcastOptions;
87import android.app.Dialog;
88import android.app.IActivityContainer;
89import android.app.IActivityContainerCallback;
90import android.app.IActivityController;
91import android.app.IAppTask;
92import android.app.IApplicationThread;
93import android.app.IInstrumentationWatcher;
94import android.app.INotificationManager;
95import android.app.IProcessObserver;
96import android.app.IServiceConnection;
97import android.app.IStopUserCallback;
98import android.app.ITaskStackListener;
99import android.app.IUiAutomationConnection;
100import android.app.IUidObserver;
101import android.app.IUserSwitchObserver;
102import android.app.Instrumentation;
103import android.app.Notification;
104import android.app.NotificationManager;
105import android.app.PendingIntent;
106import android.app.ProfilerInfo;
107import android.app.admin.DevicePolicyManager;
108import android.app.assist.AssistContent;
109import android.app.assist.AssistStructure;
110import android.app.backup.IBackupManager;
111import android.app.usage.UsageEvents;
112import android.app.usage.UsageStatsManagerInternal;
113import android.appwidget.AppWidgetManager;
114import android.content.ActivityNotFoundException;
115import android.content.BroadcastReceiver;
116import android.content.ClipData;
117import android.content.ComponentCallbacks2;
118import android.content.ComponentName;
119import android.content.ContentProvider;
120import android.content.ContentResolver;
121import android.content.Context;
122import android.content.DialogInterface;
123import android.content.IContentProvider;
124import android.content.IIntentReceiver;
125import android.content.IIntentSender;
126import android.content.Intent;
127import android.content.IntentFilter;
128import android.content.IntentSender;
129import android.content.pm.ActivityInfo;
130import android.content.pm.ApplicationInfo;
131import android.content.pm.ConfigurationInfo;
132import android.content.pm.IPackageDataObserver;
133import android.content.pm.IPackageManager;
134import android.content.pm.InstrumentationInfo;
135import android.content.pm.PackageInfo;
136import android.content.pm.PackageManager;
137import android.content.pm.PackageManager.NameNotFoundException;
138import android.content.pm.PackageManagerInternal;
139import android.content.pm.ParceledListSlice;
140import android.content.pm.PathPermission;
141import android.content.pm.PermissionInfo;
142import android.content.pm.ProviderInfo;
143import android.content.pm.ResolveInfo;
144import android.content.pm.ServiceInfo;
145import android.content.pm.UserInfo;
146import android.content.res.CompatibilityInfo;
147import android.content.res.Configuration;
148import android.content.res.Resources;
149import android.database.ContentObserver;
150import android.graphics.Bitmap;
151import android.graphics.Point;
152import android.graphics.Rect;
153import android.location.LocationManager;
154import android.net.Proxy;
155import android.net.ProxyInfo;
156import android.net.Uri;
157import android.os.BatteryStats;
158import android.os.Binder;
159import android.os.Build;
160import android.os.Bundle;
161import android.os.Debug;
162import android.os.DropBoxManager;
163import android.os.Environment;
164import android.os.FactoryTest;
165import android.os.FileObserver;
166import android.os.FileUtils;
167import android.os.Handler;
168import android.os.IBinder;
169import android.os.IPermissionController;
170import android.os.IProcessInfoService;
171import android.os.IProgressListener;
172import android.os.LocaleList;
173import android.os.Looper;
174import android.os.Message;
175import android.os.Parcel;
176import android.os.ParcelFileDescriptor;
177import android.os.PersistableBundle;
178import android.os.PowerManager;
179import android.os.PowerManagerInternal;
180import android.os.Process;
181import android.os.RemoteCallbackList;
182import android.os.RemoteException;
183import android.os.ResultReceiver;
184import android.os.ServiceManager;
185import android.os.ShellCallback;
186import android.os.StrictMode;
187import android.os.SystemClock;
188import android.os.SystemProperties;
189import android.os.Trace;
190import android.os.TransactionTooLargeException;
191import android.os.UpdateLock;
192import android.os.UserHandle;
193import android.os.UserManager;
194import android.os.WorkSource;
195import android.os.storage.IMountService;
196import android.os.storage.MountServiceInternal;
197import android.os.storage.StorageManager;
198import android.provider.Settings;
199import android.service.voice.IVoiceInteractionSession;
200import android.service.voice.VoiceInteractionManagerInternal;
201import android.service.voice.VoiceInteractionSession;
202import android.telecom.TelecomManager;
203import android.text.format.DateUtils;
204import android.text.format.Time;
205import android.text.style.SuggestionSpan;
206import android.util.ArrayMap;
207import android.util.ArraySet;
208import android.util.AtomicFile;
209import android.util.DebugUtils;
210import android.util.DisplayMetrics;
211import android.util.EventLog;
212import android.util.Log;
213import android.util.Pair;
214import android.util.PrintWriterPrinter;
215import android.util.Slog;
216import android.util.SparseArray;
217import android.util.TimeUtils;
218import android.util.Xml;
219import android.view.Display;
220import android.view.Gravity;
221import android.view.LayoutInflater;
222import android.view.View;
223import android.view.WindowManager;
224
225import java.io.File;
226import java.io.FileDescriptor;
227import java.io.FileInputStream;
228import java.io.FileNotFoundException;
229import java.io.FileOutputStream;
230import java.io.IOException;
231import java.io.InputStreamReader;
232import java.io.PrintWriter;
233import java.io.StringWriter;
234import java.lang.ref.WeakReference;
235import java.nio.charset.StandardCharsets;
236import java.util.ArrayList;
237import java.util.Arrays;
238import java.util.Collections;
239import java.util.Comparator;
240import java.util.HashMap;
241import java.util.HashSet;
242import java.util.Iterator;
243import java.util.List;
244import java.util.Locale;
245import java.util.Map;
246import java.util.Objects;
247import java.util.Set;
248import java.util.concurrent.atomic.AtomicBoolean;
249import java.util.concurrent.atomic.AtomicLong;
250
251import dalvik.system.VMRuntime;
252
253import libcore.io.IoUtils;
254import libcore.util.EmptyArray;
255
256import static android.Manifest.permission.INTERACT_ACROSS_USERS;
257import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
258import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
259import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
260import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
261import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
262import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
263import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
264import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
265import static android.app.ActivityManager.StackId.HOME_STACK_ID;
266import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
267import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
268import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
269import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
270import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
271import static android.content.pm.PackageManager.GET_PROVIDERS;
272import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
273import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
274import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
275import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
276import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
277import static android.content.pm.PackageManager.PERMISSION_GRANTED;
278import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
279import static android.os.Process.PROC_CHAR;
280import static android.os.Process.PROC_OUT_LONG;
281import static android.os.Process.PROC_PARENS;
282import static android.os.Process.PROC_SPACE_TERM;
283import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
284import static android.provider.Settings.Global.DEBUG_APP;
285import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
286import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
287import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
288import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
289import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
290import static android.provider.Settings.System.FONT_SCALE;
291import static com.android.internal.util.XmlUtils.readBooleanAttribute;
292import static com.android.internal.util.XmlUtils.readIntAttribute;
293import static com.android.internal.util.XmlUtils.readLongAttribute;
294import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
295import static com.android.internal.util.XmlUtils.writeIntAttribute;
296import static com.android.internal.util.XmlUtils.writeLongAttribute;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
301import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
302import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
303import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
304import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
315import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
316import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
317import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
318import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
319import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
320import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
321import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
322import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
323import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
324import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
325import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
326import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
327import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
328import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
329import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
330import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
331import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
332import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
333import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
334import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
335import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
336import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
337import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
338import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
339import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
340import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
341import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
342import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
343import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
344import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
345import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
346import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
347import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
348import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
349import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
350import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
351import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
352import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
353import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
354import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
355import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
356import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
357import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
358import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
359import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
360import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
361import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
362import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
363import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
364import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
365import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
366import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
367import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
368import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
369import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
370import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
371import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
372import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
373import static org.xmlpull.v1.XmlPullParser.START_TAG;
374
375public final class ActivityManagerService extends ActivityManagerNative
376        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
377
378    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
379    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
380    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
381    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
382    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
383    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
384    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
385    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
386    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
387    private static final String TAG_LRU = TAG + POSTFIX_LRU;
388    private static final String TAG_MU = TAG + POSTFIX_MU;
389    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
390    private static final String TAG_POWER = TAG + POSTFIX_POWER;
391    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
392    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
393    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
394    private static final String TAG_PSS = TAG + POSTFIX_PSS;
395    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
396    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
397    private static final String TAG_STACK = TAG + POSTFIX_STACK;
398    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
399    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
400    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
401    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
402    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
403
404    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
405    // here so that while the job scheduler can depend on AMS, the other way around
406    // need not be the case.
407    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
408
409    /** Control over CPU and battery monitoring */
410    // write battery stats every 30 minutes.
411    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
412    static final boolean MONITOR_CPU_USAGE = true;
413    // don't sample cpu less than every 5 seconds.
414    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
415    // wait possibly forever for next cpu sample.
416    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
417    static final boolean MONITOR_THREAD_CPU_USAGE = false;
418
419    // The flags that are set for all calls we make to the package manager.
420    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
421
422    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
423
424    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
425
426    // Amount of time after a call to stopAppSwitches() during which we will
427    // prevent further untrusted switches from happening.
428    static final long APP_SWITCH_DELAY_TIME = 5*1000;
429
430    // How long we wait for a launched process to attach to the activity manager
431    // before we decide it's never going to come up for real.
432    static final int PROC_START_TIMEOUT = 10*1000;
433    // How long we wait for an attached process to publish its content providers
434    // before we decide it must be hung.
435    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
436
437    // How long we will retain processes hosting content providers in the "last activity"
438    // state before allowing them to drop down to the regular cached LRU list.  This is
439    // to avoid thrashing of provider processes under low memory situations.
440    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
441
442    // How long we wait for a launched process to attach to the activity manager
443    // before we decide it's never going to come up for real, when the process was
444    // started with a wrapper for instrumentation (such as Valgrind) because it
445    // could take much longer than usual.
446    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
447
448    // How long to wait after going idle before forcing apps to GC.
449    static final int GC_TIMEOUT = 5*1000;
450
451    // The minimum amount of time between successive GC requests for a process.
452    static final int GC_MIN_INTERVAL = 60*1000;
453
454    // The minimum amount of time between successive PSS requests for a process.
455    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
456
457    // The minimum amount of time between successive PSS requests for a process
458    // when the request is due to the memory state being lowered.
459    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
460
461    // The rate at which we check for apps using excessive power -- 15 mins.
462    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
463
464    // The minimum sample duration we will allow before deciding we have
465    // enough data on wake locks to start killing things.
466    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
467
468    // The minimum sample duration we will allow before deciding we have
469    // enough data on CPU usage to start killing things.
470    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
471
472    // How long we allow a receiver to run before giving up on it.
473    static final int BROADCAST_FG_TIMEOUT = 10*1000;
474    static final int BROADCAST_BG_TIMEOUT = 60*1000;
475
476    // How long we wait until we timeout on key dispatching.
477    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
478
479    // How long we wait until we timeout on key dispatching during instrumentation.
480    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
481
482    // This is the amount of time an app needs to be running a foreground service before
483    // we will consider it to be doing interaction for usage stats.
484    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
485
486    // Maximum amount of time we will allow to elapse before re-reporting usage stats
487    // interaction with foreground processes.
488    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
489
490    // This is the amount of time we allow an app to settle after it goes into the background,
491    // before we start restricting what it can do.
492    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
493
494    // How long to wait in getAssistContextExtras for the activity and foreground services
495    // to respond with the result.
496    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
497
498    // How long top wait when going through the modern assist (which doesn't need to block
499    // on getting this result before starting to launch its UI).
500    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
501
502    // Maximum number of persisted Uri grants a package is allowed
503    static final int MAX_PERSISTED_URI_GRANTS = 128;
504
505    static final int MY_PID = Process.myPid();
506
507    static final String[] EMPTY_STRING_ARRAY = new String[0];
508
509    // How many bytes to write into the dropbox log before truncating
510    static final int DROPBOX_MAX_SIZE = 192 * 1024;
511    // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
512    // as one line, but close enough for now.
513    static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
514
515    // Access modes for handleIncomingUser.
516    static final int ALLOW_NON_FULL = 0;
517    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
518    static final int ALLOW_FULL_ONLY = 2;
519
520    // Delay in notifying task stack change listeners (in millis)
521    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
522
523    // Necessary ApplicationInfo flags to mark an app as persistent
524    private static final int PERSISTENT_MASK =
525            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
526
527    // Intent sent when remote bugreport collection has been completed
528    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
529            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
530
531    // Used to indicate that a task is removed it should also be removed from recents.
532    private static final boolean REMOVE_FROM_RECENTS = true;
533    // Used to indicate that an app transition should be animated.
534    static final boolean ANIMATE = true;
535
536    // Determines whether to take full screen screenshots
537    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
538    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
539
540    /** All system services */
541    SystemServiceManager mSystemServiceManager;
542
543    private Installer mInstaller;
544
545    /** Run all ActivityStacks through this */
546    final ActivityStackSupervisor mStackSupervisor;
547
548    final ActivityStarter mActivityStarter;
549
550    /** Task stack change listeners. */
551    private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
552            new RemoteCallbackList<ITaskStackListener>();
553
554    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
555
556    public IntentFirewall mIntentFirewall;
557
558    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
559    // default action automatically.  Important for devices without direct input
560    // devices.
561    private boolean mShowDialogs = true;
562    private boolean mInVrMode = false;
563
564    // Whether we should use SCHED_FIFO for UI and RenderThreads.
565    private boolean mUseFifoUiScheduling = false;
566
567    BroadcastQueue mFgBroadcastQueue;
568    BroadcastQueue mBgBroadcastQueue;
569    // Convenient for easy iteration over the queues. Foreground is first
570    // so that dispatch of foreground broadcasts gets precedence.
571    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
572
573    BroadcastStats mLastBroadcastStats;
574    BroadcastStats mCurBroadcastStats;
575
576    BroadcastQueue broadcastQueueForIntent(Intent intent) {
577        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
578        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
579                "Broadcast intent " + intent + " on "
580                + (isFg ? "foreground" : "background") + " queue");
581        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
582    }
583
584    /**
585     * The last resumed activity. This is identical to the current resumed activity most
586     * of the time but could be different when we're pausing one activity before we resume
587     * another activity.
588     */
589    private ActivityRecord mLastResumedActivity;
590
591    /**
592     * If non-null, we are tracking the time the user spends in the currently focused app.
593     */
594    private AppTimeTracker mCurAppTimeTracker;
595
596    /**
597     * List of intents that were used to start the most recent tasks.
598     */
599    final RecentTasks mRecentTasks;
600
601    /**
602     * For addAppTask: cached of the last activity component that was added.
603     */
604    ComponentName mLastAddedTaskComponent;
605
606    /**
607     * For addAppTask: cached of the last activity uid that was added.
608     */
609    int mLastAddedTaskUid;
610
611    /**
612     * For addAppTask: cached of the last ActivityInfo that was added.
613     */
614    ActivityInfo mLastAddedTaskActivity;
615
616    /**
617     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
618     */
619    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
620
621    /**
622     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
623     */
624    String mDeviceOwnerName;
625
626    final UserController mUserController;
627
628    final AppErrors mAppErrors;
629
630    public boolean canShowErrorDialogs() {
631        return mShowDialogs && !mSleeping && !mShuttingDown
632                && mLockScreenShown != LOCK_SCREEN_SHOWN;
633    }
634
635    private static final class PriorityState {
636        // Acts as counter for number of synchronized region that needs to acquire 'this' as a lock
637        // the current thread is currently in. When it drops down to zero, we will no longer boost
638        // the thread's priority.
639        private int regionCounter = 0;
640
641        // The thread's previous priority before boosting.
642        private int prevPriority = Integer.MIN_VALUE;
643    }
644
645    static ThreadLocal<PriorityState> sThreadPriorityState = new ThreadLocal<PriorityState>() {
646        @Override protected PriorityState initialValue() {
647            return new PriorityState();
648        }
649    };
650
651    static void boostPriorityForLockedSection() {
652        int tid = Process.myTid();
653        int prevPriority = Process.getThreadPriority(tid);
654        PriorityState state = sThreadPriorityState.get();
655        if (state.regionCounter == 0 && prevPriority > -2) {
656            state.prevPriority = prevPriority;
657            Process.setThreadPriority(tid, -2);
658        }
659        state.regionCounter++;
660    }
661
662    static void resetPriorityAfterLockedSection() {
663        PriorityState state = sThreadPriorityState.get();
664        state.regionCounter--;
665        if (state.regionCounter == 0 && state.prevPriority > -2) {
666            Process.setThreadPriority(Process.myTid(), state.prevPriority);
667        }
668    }
669
670    public class PendingAssistExtras extends Binder implements Runnable {
671        public final ActivityRecord activity;
672        public final Bundle extras;
673        public final Intent intent;
674        public final String hint;
675        public final IResultReceiver receiver;
676        public final int userHandle;
677        public boolean haveResult = false;
678        public Bundle result = null;
679        public AssistStructure structure = null;
680        public AssistContent content = null;
681        public Bundle receiverExtras;
682
683        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
684                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
685            activity = _activity;
686            extras = _extras;
687            intent = _intent;
688            hint = _hint;
689            receiver = _receiver;
690            receiverExtras = _receiverExtras;
691            userHandle = _userHandle;
692        }
693        @Override
694        public void run() {
695            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
696            synchronized (this) {
697                haveResult = true;
698                notifyAll();
699            }
700            pendingAssistExtrasTimedOut(this);
701        }
702    }
703
704    final ArrayList<PendingAssistExtras> mPendingAssistExtras
705            = new ArrayList<PendingAssistExtras>();
706
707    /**
708     * Process management.
709     */
710    final ProcessList mProcessList = new ProcessList();
711
712    /**
713     * All of the applications we currently have running organized by name.
714     * The keys are strings of the application package name (as
715     * returned by the package manager), and the keys are ApplicationRecord
716     * objects.
717     */
718    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
719
720    /**
721     * Tracking long-term execution of processes to look for abuse and other
722     * bad app behavior.
723     */
724    final ProcessStatsService mProcessStats;
725
726    /**
727     * The currently running isolated processes.
728     */
729    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
730
731    /**
732     * Counter for assigning isolated process uids, to avoid frequently reusing the
733     * same ones.
734     */
735    int mNextIsolatedProcessUid = 0;
736
737    /**
738     * The currently running heavy-weight process, if any.
739     */
740    ProcessRecord mHeavyWeightProcess = null;
741
742    /**
743     * All of the processes we currently have running organized by pid.
744     * The keys are the pid running the application.
745     *
746     * <p>NOTE: This object is protected by its own lock, NOT the global
747     * activity manager lock!
748     */
749    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
750
751    /**
752     * All of the processes that have been forced to be foreground.  The key
753     * is the pid of the caller who requested it (we hold a death
754     * link on it).
755     */
756    abstract class ForegroundToken implements IBinder.DeathRecipient {
757        int pid;
758        IBinder token;
759    }
760    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
761
762    /**
763     * List of records for processes that someone had tried to start before the
764     * system was ready.  We don't start them at that point, but ensure they
765     * are started by the time booting is complete.
766     */
767    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
768
769    /**
770     * List of persistent applications that are in the process
771     * of being started.
772     */
773    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
774
775    /**
776     * Processes that are being forcibly torn down.
777     */
778    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
779
780    /**
781     * List of running applications, sorted by recent usage.
782     * The first entry in the list is the least recently used.
783     */
784    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
785
786    /**
787     * Where in mLruProcesses that the processes hosting activities start.
788     */
789    int mLruProcessActivityStart = 0;
790
791    /**
792     * Where in mLruProcesses that the processes hosting services start.
793     * This is after (lower index) than mLruProcessesActivityStart.
794     */
795    int mLruProcessServiceStart = 0;
796
797    /**
798     * List of processes that should gc as soon as things are idle.
799     */
800    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
801
802    /**
803     * Processes we want to collect PSS data from.
804     */
805    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
806
807    private boolean mBinderTransactionTrackingEnabled = false;
808
809    /**
810     * Last time we requested PSS data of all processes.
811     */
812    long mLastFullPssTime = SystemClock.uptimeMillis();
813
814    /**
815     * If set, the next time we collect PSS data we should do a full collection
816     * with data from native processes and the kernel.
817     */
818    boolean mFullPssPending = false;
819
820    /**
821     * This is the process holding what we currently consider to be
822     * the "home" activity.
823     */
824    ProcessRecord mHomeProcess;
825
826    /**
827     * This is the process holding the activity the user last visited that
828     * is in a different process from the one they are currently in.
829     */
830    ProcessRecord mPreviousProcess;
831
832    /**
833     * The time at which the previous process was last visible.
834     */
835    long mPreviousProcessVisibleTime;
836
837    /**
838     * Track all uids that have actively running processes.
839     */
840    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
841
842    /**
843     * This is for verifying the UID report flow.
844     */
845    static final boolean VALIDATE_UID_STATES = true;
846    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
847
848    /**
849     * Packages that the user has asked to have run in screen size
850     * compatibility mode instead of filling the screen.
851     */
852    final CompatModePackages mCompatModePackages;
853
854    /**
855     * Set of IntentSenderRecord objects that are currently active.
856     */
857    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
858            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
859
860    /**
861     * Fingerprints (hashCode()) of stack traces that we've
862     * already logged DropBox entries for.  Guarded by itself.  If
863     * something (rogue user app) forces this over
864     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
865     */
866    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
867    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
868
869    /**
870     * Strict Mode background batched logging state.
871     *
872     * The string buffer is guarded by itself, and its lock is also
873     * used to determine if another batched write is already
874     * in-flight.
875     */
876    private final StringBuilder mStrictModeBuffer = new StringBuilder();
877
878    /**
879     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
880     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
881     */
882    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
883
884    /**
885     * Resolver for broadcast intents to registered receivers.
886     * Holds BroadcastFilter (subclass of IntentFilter).
887     */
888    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
889            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
890        @Override
891        protected boolean allowFilterResult(
892                BroadcastFilter filter, List<BroadcastFilter> dest) {
893            IBinder target = filter.receiverList.receiver.asBinder();
894            for (int i = dest.size() - 1; i >= 0; i--) {
895                if (dest.get(i).receiverList.receiver.asBinder() == target) {
896                    return false;
897                }
898            }
899            return true;
900        }
901
902        @Override
903        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
904            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
905                    || userId == filter.owningUserId) {
906                return super.newResult(filter, match, userId);
907            }
908            return null;
909        }
910
911        @Override
912        protected BroadcastFilter[] newArray(int size) {
913            return new BroadcastFilter[size];
914        }
915
916        @Override
917        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
918            return packageName.equals(filter.packageName);
919        }
920    };
921
922    /**
923     * State of all active sticky broadcasts per user.  Keys are the action of the
924     * sticky Intent, values are an ArrayList of all broadcasted intents with
925     * that action (which should usually be one).  The SparseArray is keyed
926     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
927     * for stickies that are sent to all users.
928     */
929    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
930            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
931
932    final ActiveServices mServices;
933
934    final static class Association {
935        final int mSourceUid;
936        final String mSourceProcess;
937        final int mTargetUid;
938        final ComponentName mTargetComponent;
939        final String mTargetProcess;
940
941        int mCount;
942        long mTime;
943
944        int mNesting;
945        long mStartTime;
946
947        // states of the source process when the bind occurred.
948        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
949        long mLastStateUptime;
950        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
951                - ActivityManager.MIN_PROCESS_STATE+1];
952
953        Association(int sourceUid, String sourceProcess, int targetUid,
954                ComponentName targetComponent, String targetProcess) {
955            mSourceUid = sourceUid;
956            mSourceProcess = sourceProcess;
957            mTargetUid = targetUid;
958            mTargetComponent = targetComponent;
959            mTargetProcess = targetProcess;
960        }
961    }
962
963    /**
964     * When service association tracking is enabled, this is all of the associations we
965     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
966     * -> association data.
967     */
968    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
969            mAssociations = new SparseArray<>();
970    boolean mTrackingAssociations;
971
972    /**
973     * Backup/restore process management
974     */
975    String mBackupAppName = null;
976    BackupRecord mBackupTarget = null;
977
978    final ProviderMap mProviderMap;
979
980    /**
981     * List of content providers who have clients waiting for them.  The
982     * application is currently being launched and the provider will be
983     * removed from this list once it is published.
984     */
985    final ArrayList<ContentProviderRecord> mLaunchingProviders
986            = new ArrayList<ContentProviderRecord>();
987
988    /**
989     * File storing persisted {@link #mGrantedUriPermissions}.
990     */
991    private final AtomicFile mGrantFile;
992
993    /** XML constants used in {@link #mGrantFile} */
994    private static final String TAG_URI_GRANTS = "uri-grants";
995    private static final String TAG_URI_GRANT = "uri-grant";
996    private static final String ATTR_USER_HANDLE = "userHandle";
997    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
998    private static final String ATTR_TARGET_USER_ID = "targetUserId";
999    private static final String ATTR_SOURCE_PKG = "sourcePkg";
1000    private static final String ATTR_TARGET_PKG = "targetPkg";
1001    private static final String ATTR_URI = "uri";
1002    private static final String ATTR_MODE_FLAGS = "modeFlags";
1003    private static final String ATTR_CREATED_TIME = "createdTime";
1004    private static final String ATTR_PREFIX = "prefix";
1005
1006    /**
1007     * Global set of specific {@link Uri} permissions that have been granted.
1008     * This optimized lookup structure maps from {@link UriPermission#targetUid}
1009     * to {@link UriPermission#uri} to {@link UriPermission}.
1010     */
1011    @GuardedBy("this")
1012    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1013            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1014
1015    public static class GrantUri {
1016        public final int sourceUserId;
1017        public final Uri uri;
1018        public boolean prefix;
1019
1020        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1021            this.sourceUserId = sourceUserId;
1022            this.uri = uri;
1023            this.prefix = prefix;
1024        }
1025
1026        @Override
1027        public int hashCode() {
1028            int hashCode = 1;
1029            hashCode = 31 * hashCode + sourceUserId;
1030            hashCode = 31 * hashCode + uri.hashCode();
1031            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1032            return hashCode;
1033        }
1034
1035        @Override
1036        public boolean equals(Object o) {
1037            if (o instanceof GrantUri) {
1038                GrantUri other = (GrantUri) o;
1039                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1040                        && prefix == other.prefix;
1041            }
1042            return false;
1043        }
1044
1045        @Override
1046        public String toString() {
1047            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1048            if (prefix) result += " [prefix]";
1049            return result;
1050        }
1051
1052        public String toSafeString() {
1053            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1054            if (prefix) result += " [prefix]";
1055            return result;
1056        }
1057
1058        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1059            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1060                    ContentProvider.getUriWithoutUserId(uri), false);
1061        }
1062    }
1063
1064    CoreSettingsObserver mCoreSettingsObserver;
1065
1066    FontScaleSettingObserver mFontScaleSettingObserver;
1067
1068    private final class FontScaleSettingObserver extends ContentObserver {
1069        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1070
1071        public FontScaleSettingObserver() {
1072            super(mHandler);
1073            ContentResolver resolver = mContext.getContentResolver();
1074            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1075        }
1076
1077        @Override
1078        public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1079            if (mFontScaleUri.equals(uri)) {
1080                updateFontScaleIfNeeded(userId);
1081            }
1082        }
1083    }
1084
1085    /**
1086     * Thread-local storage used to carry caller permissions over through
1087     * indirect content-provider access.
1088     */
1089    private class Identity {
1090        public final IBinder token;
1091        public final int pid;
1092        public final int uid;
1093
1094        Identity(IBinder _token, int _pid, int _uid) {
1095            token = _token;
1096            pid = _pid;
1097            uid = _uid;
1098        }
1099    }
1100
1101    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1102
1103    /**
1104     * All information we have collected about the runtime performance of
1105     * any user id that can impact battery performance.
1106     */
1107    final BatteryStatsService mBatteryStatsService;
1108
1109    /**
1110     * Information about component usage
1111     */
1112    UsageStatsManagerInternal mUsageStatsService;
1113
1114    /**
1115     * Access to DeviceIdleController service.
1116     */
1117    DeviceIdleController.LocalService mLocalDeviceIdleController;
1118
1119    /**
1120     * Information about and control over application operations
1121     */
1122    final AppOpsService mAppOpsService;
1123
1124    /** Current sequencing integer of the configuration, for skipping old configurations. */
1125    private int mConfigurationSeq;
1126
1127    /**
1128     * Temp object used when global configuration is updated. It is also sent to outer world
1129     * instead of {@link #getGlobalConfiguration} because we don't trust anyone...
1130     */
1131    private Configuration mTempGlobalConfig = new Configuration();
1132
1133    private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
1134            new UpdateConfigurationResult();
1135    private static final class UpdateConfigurationResult {
1136        // Configuration changes that were updated.
1137        int changes;
1138        // If the activity was relaunched to match the new configuration.
1139        boolean activityRelaunched;
1140
1141        void reset() {
1142            changes = 0;
1143            activityRelaunched = false;
1144        }
1145    }
1146
1147    boolean mSuppressResizeConfigChanges;
1148
1149    /**
1150     * Hardware-reported OpenGLES version.
1151     */
1152    final int GL_ES_VERSION;
1153
1154    /**
1155     * List of initialization arguments to pass to all processes when binding applications to them.
1156     * For example, references to the commonly used services.
1157     */
1158    HashMap<String, IBinder> mAppBindArgs;
1159    HashMap<String, IBinder> mIsolatedAppBindArgs;
1160
1161    /**
1162     * Temporary to avoid allocations.  Protected by main lock.
1163     */
1164    final StringBuilder mStringBuilder = new StringBuilder(256);
1165
1166    /**
1167     * Used to control how we initialize the service.
1168     */
1169    ComponentName mTopComponent;
1170    String mTopAction = Intent.ACTION_MAIN;
1171    String mTopData;
1172
1173    volatile boolean mProcessesReady = false;
1174    volatile boolean mSystemReady = false;
1175    volatile boolean mOnBattery = false;
1176    volatile int mFactoryTest;
1177
1178    @GuardedBy("this") boolean mBooting = false;
1179    @GuardedBy("this") boolean mCallFinishBooting = false;
1180    @GuardedBy("this") boolean mBootAnimationComplete = false;
1181    @GuardedBy("this") boolean mLaunchWarningShown = false;
1182    @GuardedBy("this") boolean mCheckedForSetup = false;
1183
1184    Context mContext;
1185
1186    /**
1187     * The time at which we will allow normal application switches again,
1188     * after a call to {@link #stopAppSwitches()}.
1189     */
1190    long mAppSwitchesAllowedTime;
1191
1192    /**
1193     * This is set to true after the first switch after mAppSwitchesAllowedTime
1194     * is set; any switches after that will clear the time.
1195     */
1196    boolean mDidAppSwitch;
1197
1198    /**
1199     * Last time (in realtime) at which we checked for power usage.
1200     */
1201    long mLastPowerCheckRealtime;
1202
1203    /**
1204     * Last time (in uptime) at which we checked for power usage.
1205     */
1206    long mLastPowerCheckUptime;
1207
1208    /**
1209     * Set while we are wanting to sleep, to prevent any
1210     * activities from being started/resumed.
1211     */
1212    private boolean mSleeping = false;
1213
1214    /**
1215     * The process state used for processes that are running the top activities.
1216     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1217     */
1218    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1219
1220    /**
1221     * Set while we are running a voice interaction.  This overrides
1222     * sleeping while it is active.
1223     */
1224    private IVoiceInteractionSession mRunningVoice;
1225
1226    /**
1227     * For some direct access we need to power manager.
1228     */
1229    PowerManagerInternal mLocalPowerManager;
1230
1231    /**
1232     * We want to hold a wake lock while running a voice interaction session, since
1233     * this may happen with the screen off and we need to keep the CPU running to
1234     * be able to continue to interact with the user.
1235     */
1236    PowerManager.WakeLock mVoiceWakeLock;
1237
1238    /**
1239     * State of external calls telling us if the device is awake or asleep.
1240     */
1241    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1242
1243    /**
1244     * A list of tokens that cause the top activity to be put to sleep.
1245     * They are used by components that may hide and block interaction with underlying
1246     * activities.
1247     */
1248    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1249
1250    static final int LOCK_SCREEN_HIDDEN = 0;
1251    static final int LOCK_SCREEN_LEAVING = 1;
1252    static final int LOCK_SCREEN_SHOWN = 2;
1253    /**
1254     * State of external call telling us if the lock screen is shown.
1255     */
1256    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1257
1258    /**
1259     * Set if we are shutting down the system, similar to sleeping.
1260     */
1261    boolean mShuttingDown = false;
1262
1263    /**
1264     * Current sequence id for oom_adj computation traversal.
1265     */
1266    int mAdjSeq = 0;
1267
1268    /**
1269     * Current sequence id for process LRU updating.
1270     */
1271    int mLruSeq = 0;
1272
1273    /**
1274     * Keep track of the non-cached/empty process we last found, to help
1275     * determine how to distribute cached/empty processes next time.
1276     */
1277    int mNumNonCachedProcs = 0;
1278
1279    /**
1280     * Keep track of the number of cached hidden procs, to balance oom adj
1281     * distribution between those and empty procs.
1282     */
1283    int mNumCachedHiddenProcs = 0;
1284
1285    /**
1286     * Keep track of the number of service processes we last found, to
1287     * determine on the next iteration which should be B services.
1288     */
1289    int mNumServiceProcs = 0;
1290    int mNewNumAServiceProcs = 0;
1291    int mNewNumServiceProcs = 0;
1292
1293    /**
1294     * Allow the current computed overall memory level of the system to go down?
1295     * This is set to false when we are killing processes for reasons other than
1296     * memory management, so that the now smaller process list will not be taken as
1297     * an indication that memory is tighter.
1298     */
1299    boolean mAllowLowerMemLevel = false;
1300
1301    /**
1302     * The last computed memory level, for holding when we are in a state that
1303     * processes are going away for other reasons.
1304     */
1305    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1306
1307    /**
1308     * The last total number of process we have, to determine if changes actually look
1309     * like a shrinking number of process due to lower RAM.
1310     */
1311    int mLastNumProcesses;
1312
1313    /**
1314     * The uptime of the last time we performed idle maintenance.
1315     */
1316    long mLastIdleTime = SystemClock.uptimeMillis();
1317
1318    /**
1319     * Total time spent with RAM that has been added in the past since the last idle time.
1320     */
1321    long mLowRamTimeSinceLastIdle = 0;
1322
1323    /**
1324     * If RAM is currently low, when that horrible situation started.
1325     */
1326    long mLowRamStartTime = 0;
1327
1328    /**
1329     * For reporting to battery stats the current top application.
1330     */
1331    private String mCurResumedPackage = null;
1332    private int mCurResumedUid = -1;
1333
1334    /**
1335     * For reporting to battery stats the apps currently running foreground
1336     * service.  The ProcessMap is package/uid tuples; each of these contain
1337     * an array of the currently foreground processes.
1338     */
1339    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1340            = new ProcessMap<ArrayList<ProcessRecord>>();
1341
1342    /**
1343     * This is set if we had to do a delayed dexopt of an app before launching
1344     * it, to increase the ANR timeouts in that case.
1345     */
1346    boolean mDidDexOpt;
1347
1348    /**
1349     * Set if the systemServer made a call to enterSafeMode.
1350     */
1351    boolean mSafeMode;
1352
1353    /**
1354     * If true, we are running under a test environment so will sample PSS from processes
1355     * much more rapidly to try to collect better data when the tests are rapidly
1356     * running through apps.
1357     */
1358    boolean mTestPssMode = false;
1359
1360    String mDebugApp = null;
1361    boolean mWaitForDebugger = false;
1362    boolean mDebugTransient = false;
1363    String mOrigDebugApp = null;
1364    boolean mOrigWaitForDebugger = false;
1365    boolean mAlwaysFinishActivities = false;
1366    boolean mLenientBackgroundCheck = false;
1367    boolean mForceResizableActivities;
1368    boolean mSupportsMultiWindow;
1369    boolean mSupportsFreeformWindowManagement;
1370    boolean mSupportsPictureInPicture;
1371    boolean mSupportsLeanbackOnly;
1372    Rect mDefaultPinnedStackBounds;
1373    IActivityController mController = null;
1374    boolean mControllerIsAMonkey = false;
1375    String mProfileApp = null;
1376    ProcessRecord mProfileProc = null;
1377    String mProfileFile;
1378    ParcelFileDescriptor mProfileFd;
1379    int mSamplingInterval = 0;
1380    boolean mAutoStopProfiler = false;
1381    int mProfileType = 0;
1382    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1383    String mMemWatchDumpProcName;
1384    String mMemWatchDumpFile;
1385    int mMemWatchDumpPid;
1386    int mMemWatchDumpUid;
1387    String mTrackAllocationApp = null;
1388    String mNativeDebuggingApp = null;
1389
1390    final long[] mTmpLong = new long[2];
1391
1392    static final class ProcessChangeItem {
1393        static final int CHANGE_ACTIVITIES = 1<<0;
1394        static final int CHANGE_PROCESS_STATE = 1<<1;
1395        int changes;
1396        int uid;
1397        int pid;
1398        int processState;
1399        boolean foregroundActivities;
1400    }
1401
1402    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1403    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1404
1405    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1406    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1407
1408    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1409    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1410
1411    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1412    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1413
1414    /**
1415     * Runtime CPU use collection thread.  This object's lock is used to
1416     * perform synchronization with the thread (notifying it to run).
1417     */
1418    final Thread mProcessCpuThread;
1419
1420    /**
1421     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1422     * Must acquire this object's lock when accessing it.
1423     * NOTE: this lock will be held while doing long operations (trawling
1424     * through all processes in /proc), so it should never be acquired by
1425     * any critical paths such as when holding the main activity manager lock.
1426     */
1427    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1428            MONITOR_THREAD_CPU_USAGE);
1429    final AtomicLong mLastCpuTime = new AtomicLong(0);
1430    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1431
1432    long mLastWriteTime = 0;
1433
1434    /**
1435     * Used to retain an update lock when the foreground activity is in
1436     * immersive mode.
1437     */
1438    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1439
1440    /**
1441     * Set to true after the system has finished booting.
1442     */
1443    boolean mBooted = false;
1444
1445    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1446    int mProcessLimitOverride = -1;
1447
1448    WindowManagerService mWindowManager;
1449    final ActivityThread mSystemThread;
1450
1451    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1452        final ProcessRecord mApp;
1453        final int mPid;
1454        final IApplicationThread mAppThread;
1455
1456        AppDeathRecipient(ProcessRecord app, int pid,
1457                IApplicationThread thread) {
1458            if (DEBUG_ALL) Slog.v(
1459                TAG, "New death recipient " + this
1460                + " for thread " + thread.asBinder());
1461            mApp = app;
1462            mPid = pid;
1463            mAppThread = thread;
1464        }
1465
1466        @Override
1467        public void binderDied() {
1468            if (DEBUG_ALL) Slog.v(
1469                TAG, "Death received in " + this
1470                + " for thread " + mAppThread.asBinder());
1471            synchronized(ActivityManagerService.this) {
1472                appDiedLocked(mApp, mPid, mAppThread, true);
1473            }
1474        }
1475    }
1476
1477    static final int SHOW_ERROR_UI_MSG = 1;
1478    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1479    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1480    static final int UPDATE_CONFIGURATION_MSG = 4;
1481    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1482    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1483    static final int SERVICE_TIMEOUT_MSG = 12;
1484    static final int UPDATE_TIME_ZONE = 13;
1485    static final int SHOW_UID_ERROR_UI_MSG = 14;
1486    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1487    static final int PROC_START_TIMEOUT_MSG = 20;
1488    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1489    static final int KILL_APPLICATION_MSG = 22;
1490    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1491    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1492    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1493    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1494    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1495    static final int CLEAR_DNS_CACHE_MSG = 28;
1496    static final int UPDATE_HTTP_PROXY_MSG = 29;
1497    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1498    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1499    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1500    static final int REPORT_MEM_USAGE_MSG = 33;
1501    static final int REPORT_USER_SWITCH_MSG = 34;
1502    static final int CONTINUE_USER_SWITCH_MSG = 35;
1503    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1504    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1505    static final int PERSIST_URI_GRANTS_MSG = 38;
1506    static final int REQUEST_ALL_PSS_MSG = 39;
1507    static final int START_PROFILES_MSG = 40;
1508    static final int UPDATE_TIME = 41;
1509    static final int SYSTEM_USER_START_MSG = 42;
1510    static final int SYSTEM_USER_CURRENT_MSG = 43;
1511    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1512    static final int FINISH_BOOTING_MSG = 45;
1513    static final int START_USER_SWITCH_UI_MSG = 46;
1514    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1515    static final int DISMISS_DIALOG_UI_MSG = 48;
1516    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1517    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1518    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1519    static final int DELETE_DUMPHEAP_MSG = 52;
1520    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1521    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1522    static final int REPORT_TIME_TRACKER_MSG = 55;
1523    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1524    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1525    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1526    static final int IDLE_UIDS_MSG = 60;
1527    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1528    static final int LOG_STACK_STATE = 62;
1529    static final int VR_MODE_CHANGE_MSG = 63;
1530    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1531    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1532    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1533    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1534    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1535    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1536    static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 70;
1537    static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 71;
1538    static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 72;
1539    static final int START_USER_SWITCH_FG_MSG = 712;
1540
1541    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1542    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1543    static final int FIRST_COMPAT_MODE_MSG = 300;
1544    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1545
1546    static ServiceThread sKillThread = null;
1547    static KillHandler sKillHandler = null;
1548
1549    CompatModeDialog mCompatModeDialog;
1550    UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1551    long mLastMemUsageReportTime = 0;
1552
1553    /**
1554     * Flag whether the current user is a "monkey", i.e. whether
1555     * the UI is driven by a UI automation tool.
1556     */
1557    private boolean mUserIsMonkey;
1558
1559    /** Flag whether the device has a Recents UI */
1560    boolean mHasRecents;
1561
1562    /** The dimensions of the thumbnails in the Recents UI. */
1563    int mThumbnailWidth;
1564    int mThumbnailHeight;
1565    float mFullscreenThumbnailScale;
1566
1567    final ServiceThread mHandlerThread;
1568    final MainHandler mHandler;
1569    final UiHandler mUiHandler;
1570
1571    PackageManagerInternal mPackageManagerInt;
1572
1573    // VoiceInteraction session ID that changes for each new request except when
1574    // being called for multiwindow assist in a single session.
1575    private int mViSessionId = 1000;
1576
1577    final boolean mPermissionReviewRequired;
1578
1579    /**
1580     * Current global configuration information. Contains general settings for the entire system,
1581     * also corresponds to the merged configuration of the default display.
1582     */
1583    Configuration getGlobalConfiguration() {
1584        return mStackSupervisor.getConfiguration();
1585    }
1586
1587    final class KillHandler extends Handler {
1588        static final int KILL_PROCESS_GROUP_MSG = 4000;
1589
1590        public KillHandler(Looper looper) {
1591            super(looper, null, true);
1592        }
1593
1594        @Override
1595        public void handleMessage(Message msg) {
1596            switch (msg.what) {
1597                case KILL_PROCESS_GROUP_MSG:
1598                {
1599                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1600                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1601                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1602                }
1603                break;
1604
1605                default:
1606                    super.handleMessage(msg);
1607            }
1608        }
1609    }
1610
1611    final class UiHandler extends Handler {
1612        public UiHandler() {
1613            super(com.android.server.UiThread.get().getLooper(), null, true);
1614        }
1615
1616        @Override
1617        public void handleMessage(Message msg) {
1618            switch (msg.what) {
1619            case SHOW_ERROR_UI_MSG: {
1620                mAppErrors.handleShowAppErrorUi(msg);
1621                ensureBootCompleted();
1622            } break;
1623            case SHOW_NOT_RESPONDING_UI_MSG: {
1624                mAppErrors.handleShowAnrUi(msg);
1625                ensureBootCompleted();
1626            } break;
1627            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1628                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1629                synchronized (ActivityManagerService.this) {
1630                    ProcessRecord proc = (ProcessRecord) data.get("app");
1631                    if (proc == null) {
1632                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1633                        break;
1634                    }
1635                    if (proc.crashDialog != null) {
1636                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1637                        return;
1638                    }
1639                    AppErrorResult res = (AppErrorResult) data.get("result");
1640                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1641                        Dialog d = new StrictModeViolationDialog(mContext,
1642                                ActivityManagerService.this, res, proc);
1643                        d.show();
1644                        proc.crashDialog = d;
1645                    } else {
1646                        // The device is asleep, so just pretend that the user
1647                        // saw a crash dialog and hit "force quit".
1648                        res.set(0);
1649                    }
1650                }
1651                ensureBootCompleted();
1652            } break;
1653            case SHOW_FACTORY_ERROR_UI_MSG: {
1654                Dialog d = new FactoryErrorDialog(
1655                    mContext, msg.getData().getCharSequence("msg"));
1656                d.show();
1657                ensureBootCompleted();
1658            } break;
1659            case WAIT_FOR_DEBUGGER_UI_MSG: {
1660                synchronized (ActivityManagerService.this) {
1661                    ProcessRecord app = (ProcessRecord)msg.obj;
1662                    if (msg.arg1 != 0) {
1663                        if (!app.waitedForDebugger) {
1664                            Dialog d = new AppWaitingForDebuggerDialog(
1665                                    ActivityManagerService.this,
1666                                    mContext, app);
1667                            app.waitDialog = d;
1668                            app.waitedForDebugger = true;
1669                            d.show();
1670                        }
1671                    } else {
1672                        if (app.waitDialog != null) {
1673                            app.waitDialog.dismiss();
1674                            app.waitDialog = null;
1675                        }
1676                    }
1677                }
1678            } break;
1679            case SHOW_UID_ERROR_UI_MSG: {
1680                if (mShowDialogs) {
1681                    AlertDialog d = new BaseErrorDialog(mContext);
1682                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1683                    d.setCancelable(false);
1684                    d.setTitle(mContext.getText(R.string.android_system_label));
1685                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1686                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1687                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1688                    d.show();
1689                }
1690            } break;
1691            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1692                if (mShowDialogs) {
1693                    AlertDialog d = new BaseErrorDialog(mContext);
1694                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1695                    d.setCancelable(false);
1696                    d.setTitle(mContext.getText(R.string.android_system_label));
1697                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1698                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1699                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1700                    d.show();
1701                }
1702            } break;
1703            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1704                synchronized (ActivityManagerService.this) {
1705                    ActivityRecord ar = (ActivityRecord) msg.obj;
1706                    if (mCompatModeDialog != null) {
1707                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1708                                ar.info.applicationInfo.packageName)) {
1709                            return;
1710                        }
1711                        mCompatModeDialog.dismiss();
1712                        mCompatModeDialog = null;
1713                    }
1714                    if (ar != null && false) {
1715                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1716                                ar.packageName)) {
1717                            int mode = mCompatModePackages.computeCompatModeLocked(
1718                                    ar.info.applicationInfo);
1719                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1720                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1721                                mCompatModeDialog = new CompatModeDialog(
1722                                        ActivityManagerService.this, mContext,
1723                                        ar.info.applicationInfo);
1724                                mCompatModeDialog.show();
1725                            }
1726                        }
1727                    }
1728                }
1729                break;
1730            }
1731            case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1732                synchronized (ActivityManagerService.this) {
1733                    final ActivityRecord ar = (ActivityRecord) msg.obj;
1734                    if (mUnsupportedDisplaySizeDialog != null) {
1735                        mUnsupportedDisplaySizeDialog.dismiss();
1736                        mUnsupportedDisplaySizeDialog = null;
1737                    }
1738                    if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1739                            ar.packageName)) {
1740                        // TODO(multi-display): Show dialog on appropriate display.
1741                        mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1742                                ActivityManagerService.this, mContext, ar.info.applicationInfo);
1743                        mUnsupportedDisplaySizeDialog.show();
1744                    }
1745                }
1746                break;
1747            }
1748            case START_USER_SWITCH_UI_MSG: {
1749                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1750                break;
1751            }
1752            case DISMISS_DIALOG_UI_MSG: {
1753                final Dialog d = (Dialog) msg.obj;
1754                d.dismiss();
1755                break;
1756            }
1757            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1758                dispatchProcessesChanged();
1759                break;
1760            }
1761            case DISPATCH_PROCESS_DIED_UI_MSG: {
1762                final int pid = msg.arg1;
1763                final int uid = msg.arg2;
1764                dispatchProcessDied(pid, uid);
1765                break;
1766            }
1767            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1768                dispatchUidsChanged();
1769            } break;
1770            }
1771        }
1772    }
1773
1774    final class MainHandler extends Handler {
1775        public MainHandler(Looper looper) {
1776            super(looper, null, true);
1777        }
1778
1779        @Override
1780        public void handleMessage(Message msg) {
1781            switch (msg.what) {
1782            case UPDATE_CONFIGURATION_MSG: {
1783                final ContentResolver resolver = mContext.getContentResolver();
1784                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1785                        msg.arg1);
1786            } break;
1787            case GC_BACKGROUND_PROCESSES_MSG: {
1788                synchronized (ActivityManagerService.this) {
1789                    performAppGcsIfAppropriateLocked();
1790                }
1791            } break;
1792            case SERVICE_TIMEOUT_MSG: {
1793                if (mDidDexOpt) {
1794                    mDidDexOpt = false;
1795                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1796                    nmsg.obj = msg.obj;
1797                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1798                    return;
1799                }
1800                mServices.serviceTimeout((ProcessRecord)msg.obj);
1801            } break;
1802            case UPDATE_TIME_ZONE: {
1803                synchronized (ActivityManagerService.this) {
1804                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1805                        ProcessRecord r = mLruProcesses.get(i);
1806                        if (r.thread != null) {
1807                            try {
1808                                r.thread.updateTimeZone();
1809                            } catch (RemoteException ex) {
1810                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1811                            }
1812                        }
1813                    }
1814                }
1815            } break;
1816            case CLEAR_DNS_CACHE_MSG: {
1817                synchronized (ActivityManagerService.this) {
1818                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1819                        ProcessRecord r = mLruProcesses.get(i);
1820                        if (r.thread != null) {
1821                            try {
1822                                r.thread.clearDnsCache();
1823                            } catch (RemoteException ex) {
1824                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1825                            }
1826                        }
1827                    }
1828                }
1829            } break;
1830            case UPDATE_HTTP_PROXY_MSG: {
1831                ProxyInfo proxy = (ProxyInfo)msg.obj;
1832                String host = "";
1833                String port = "";
1834                String exclList = "";
1835                Uri pacFileUrl = Uri.EMPTY;
1836                if (proxy != null) {
1837                    host = proxy.getHost();
1838                    port = Integer.toString(proxy.getPort());
1839                    exclList = proxy.getExclusionListAsString();
1840                    pacFileUrl = proxy.getPacFileUrl();
1841                }
1842                synchronized (ActivityManagerService.this) {
1843                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1844                        ProcessRecord r = mLruProcesses.get(i);
1845                        if (r.thread != null) {
1846                            try {
1847                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1848                            } catch (RemoteException ex) {
1849                                Slog.w(TAG, "Failed to update http proxy for: " +
1850                                        r.info.processName);
1851                            }
1852                        }
1853                    }
1854                }
1855            } break;
1856            case PROC_START_TIMEOUT_MSG: {
1857                if (mDidDexOpt) {
1858                    mDidDexOpt = false;
1859                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1860                    nmsg.obj = msg.obj;
1861                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1862                    return;
1863                }
1864                ProcessRecord app = (ProcessRecord)msg.obj;
1865                synchronized (ActivityManagerService.this) {
1866                    processStartTimedOutLocked(app);
1867                }
1868            } break;
1869            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1870                ProcessRecord app = (ProcessRecord)msg.obj;
1871                synchronized (ActivityManagerService.this) {
1872                    processContentProviderPublishTimedOutLocked(app);
1873                }
1874            } break;
1875            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1876                synchronized (ActivityManagerService.this) {
1877                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1878                }
1879            } break;
1880            case KILL_APPLICATION_MSG: {
1881                synchronized (ActivityManagerService.this) {
1882                    final int appId = msg.arg1;
1883                    final int userId = msg.arg2;
1884                    Bundle bundle = (Bundle)msg.obj;
1885                    String pkg = bundle.getString("pkg");
1886                    String reason = bundle.getString("reason");
1887                    forceStopPackageLocked(pkg, appId, false, false, true, false,
1888                            false, userId, reason);
1889                }
1890            } break;
1891            case FINALIZE_PENDING_INTENT_MSG: {
1892                ((PendingIntentRecord)msg.obj).completeFinalize();
1893            } break;
1894            case POST_HEAVY_NOTIFICATION_MSG: {
1895                INotificationManager inm = NotificationManager.getService();
1896                if (inm == null) {
1897                    return;
1898                }
1899
1900                ActivityRecord root = (ActivityRecord)msg.obj;
1901                ProcessRecord process = root.app;
1902                if (process == null) {
1903                    return;
1904                }
1905
1906                try {
1907                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1908                    String text = mContext.getString(R.string.heavy_weight_notification,
1909                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1910                    Notification notification = new Notification.Builder(context)
1911                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1912                            .setWhen(0)
1913                            .setOngoing(true)
1914                            .setTicker(text)
1915                            .setColor(mContext.getColor(
1916                                    com.android.internal.R.color.system_notification_accent_color))
1917                            .setContentTitle(text)
1918                            .setContentText(
1919                                    mContext.getText(R.string.heavy_weight_notification_detail))
1920                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1921                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1922                                    new UserHandle(root.userId)))
1923                            .build();
1924                    try {
1925                        int[] outId = new int[1];
1926                        inm.enqueueNotificationWithTag("android", "android", null,
1927                                R.string.heavy_weight_notification,
1928                                notification, outId, root.userId);
1929                    } catch (RuntimeException e) {
1930                        Slog.w(ActivityManagerService.TAG,
1931                                "Error showing notification for heavy-weight app", e);
1932                    } catch (RemoteException e) {
1933                    }
1934                } catch (NameNotFoundException e) {
1935                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1936                }
1937            } break;
1938            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1939                INotificationManager inm = NotificationManager.getService();
1940                if (inm == null) {
1941                    return;
1942                }
1943                try {
1944                    inm.cancelNotificationWithTag("android", null,
1945                            R.string.heavy_weight_notification,  msg.arg1);
1946                } catch (RuntimeException e) {
1947                    Slog.w(ActivityManagerService.TAG,
1948                            "Error canceling notification for service", e);
1949                } catch (RemoteException e) {
1950                }
1951            } break;
1952            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1953                synchronized (ActivityManagerService.this) {
1954                    checkExcessivePowerUsageLocked(true);
1955                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1956                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1957                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1958                }
1959            } break;
1960            case REPORT_MEM_USAGE_MSG: {
1961                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1962                Thread thread = new Thread() {
1963                    @Override public void run() {
1964                        reportMemUsage(memInfos);
1965                    }
1966                };
1967                thread.start();
1968                break;
1969            }
1970            case START_USER_SWITCH_FG_MSG: {
1971                mUserController.startUserInForeground(msg.arg1);
1972                break;
1973            }
1974            case REPORT_USER_SWITCH_MSG: {
1975                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1976                break;
1977            }
1978            case CONTINUE_USER_SWITCH_MSG: {
1979                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1980                break;
1981            }
1982            case USER_SWITCH_TIMEOUT_MSG: {
1983                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1984                break;
1985            }
1986            case IMMERSIVE_MODE_LOCK_MSG: {
1987                final boolean nextState = (msg.arg1 != 0);
1988                if (mUpdateLock.isHeld() != nextState) {
1989                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1990                            "Applying new update lock state '" + nextState
1991                            + "' for " + (ActivityRecord)msg.obj);
1992                    if (nextState) {
1993                        mUpdateLock.acquire();
1994                    } else {
1995                        mUpdateLock.release();
1996                    }
1997                }
1998                break;
1999            }
2000            case PERSIST_URI_GRANTS_MSG: {
2001                writeGrantedUriPermissions();
2002                break;
2003            }
2004            case REQUEST_ALL_PSS_MSG: {
2005                synchronized (ActivityManagerService.this) {
2006                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
2007                }
2008                break;
2009            }
2010            case START_PROFILES_MSG: {
2011                synchronized (ActivityManagerService.this) {
2012                    mUserController.startProfilesLocked();
2013                }
2014                break;
2015            }
2016            case UPDATE_TIME: {
2017                synchronized (ActivityManagerService.this) {
2018                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2019                        ProcessRecord r = mLruProcesses.get(i);
2020                        if (r.thread != null) {
2021                            try {
2022                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
2023                            } catch (RemoteException ex) {
2024                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
2025                            }
2026                        }
2027                    }
2028                }
2029                break;
2030            }
2031            case SYSTEM_USER_START_MSG: {
2032                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2033                        Integer.toString(msg.arg1), msg.arg1);
2034                mSystemServiceManager.startUser(msg.arg1);
2035                break;
2036            }
2037            case SYSTEM_USER_UNLOCK_MSG: {
2038                final int userId = msg.arg1;
2039                mSystemServiceManager.unlockUser(userId);
2040                synchronized (ActivityManagerService.this) {
2041                    mRecentTasks.loadUserRecentsLocked(userId);
2042                }
2043                if (userId == UserHandle.USER_SYSTEM) {
2044                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2045                }
2046                installEncryptionUnawareProviders(userId);
2047                mUserController.finishUserUnlocked((UserState) msg.obj);
2048                break;
2049            }
2050            case SYSTEM_USER_CURRENT_MSG: {
2051                mBatteryStatsService.noteEvent(
2052                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2053                        Integer.toString(msg.arg2), msg.arg2);
2054                mBatteryStatsService.noteEvent(
2055                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2056                        Integer.toString(msg.arg1), msg.arg1);
2057                mSystemServiceManager.switchUser(msg.arg1);
2058                break;
2059            }
2060            case ENTER_ANIMATION_COMPLETE_MSG: {
2061                synchronized (ActivityManagerService.this) {
2062                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2063                    if (r != null && r.app != null && r.app.thread != null) {
2064                        try {
2065                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2066                        } catch (RemoteException e) {
2067                        }
2068                    }
2069                }
2070                break;
2071            }
2072            case FINISH_BOOTING_MSG: {
2073                if (msg.arg1 != 0) {
2074                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2075                    finishBooting();
2076                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2077                }
2078                if (msg.arg2 != 0) {
2079                    enableScreenAfterBoot();
2080                }
2081                break;
2082            }
2083            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2084                try {
2085                    Locale l = (Locale) msg.obj;
2086                    IBinder service = ServiceManager.getService("mount");
2087                    IMountService mountService = IMountService.Stub.asInterface(service);
2088                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2089                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2090                } catch (RemoteException e) {
2091                    Log.e(TAG, "Error storing locale for decryption UI", e);
2092                }
2093                break;
2094            }
2095            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2096                synchronized (ActivityManagerService.this) {
2097                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2098                        try {
2099                            // Make a one-way callback to the listener
2100                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2101                        } catch (RemoteException e){
2102                            // Handled by the RemoteCallbackList
2103                        }
2104                    }
2105                    mTaskStackListeners.finishBroadcast();
2106                }
2107                break;
2108            }
2109            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2110                synchronized (ActivityManagerService.this) {
2111                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2112                        try {
2113                            // Make a one-way callback to the listener
2114                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2115                        } catch (RemoteException e){
2116                            // Handled by the RemoteCallbackList
2117                        }
2118                    }
2119                    mTaskStackListeners.finishBroadcast();
2120                }
2121                break;
2122            }
2123            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2124                synchronized (ActivityManagerService.this) {
2125                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2126                        try {
2127                            // Make a one-way callback to the listener
2128                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2129                        } catch (RemoteException e){
2130                            // Handled by the RemoteCallbackList
2131                        }
2132                    }
2133                    mTaskStackListeners.finishBroadcast();
2134                }
2135                break;
2136            }
2137            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2138                synchronized (ActivityManagerService.this) {
2139                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2140                        try {
2141                            // Make a one-way callback to the listener
2142                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2143                        } catch (RemoteException e){
2144                            // Handled by the RemoteCallbackList
2145                        }
2146                    }
2147                    mTaskStackListeners.finishBroadcast();
2148                }
2149                break;
2150            }
2151            case NOTIFY_FORCED_RESIZABLE_MSG: {
2152                synchronized (ActivityManagerService.this) {
2153                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2154                        try {
2155                            // Make a one-way callback to the listener
2156                            mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2157                                    (String) msg.obj, msg.arg1);
2158                        } catch (RemoteException e){
2159                            // Handled by the RemoteCallbackList
2160                        }
2161                    }
2162                    mTaskStackListeners.finishBroadcast();
2163                }
2164                break;
2165            }
2166                case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2167                    synchronized (ActivityManagerService.this) {
2168                        for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2169                            try {
2170                                // Make a one-way callback to the listener
2171                                mTaskStackListeners.getBroadcastItem(i)
2172                                        .onActivityDismissingDockedStack();
2173                            } catch (RemoteException e){
2174                                // Handled by the RemoteCallbackList
2175                            }
2176                        }
2177                        mTaskStackListeners.finishBroadcast();
2178                    }
2179                    break;
2180                }
2181            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2182                final int uid = msg.arg1;
2183                final byte[] firstPacket = (byte[]) msg.obj;
2184
2185                synchronized (mPidsSelfLocked) {
2186                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2187                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2188                        if (p.uid == uid) {
2189                            try {
2190                                p.thread.notifyCleartextNetwork(firstPacket);
2191                            } catch (RemoteException ignored) {
2192                            }
2193                        }
2194                    }
2195                }
2196                break;
2197            }
2198            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2199                final String procName;
2200                final int uid;
2201                final long memLimit;
2202                final String reportPackage;
2203                synchronized (ActivityManagerService.this) {
2204                    procName = mMemWatchDumpProcName;
2205                    uid = mMemWatchDumpUid;
2206                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2207                    if (val == null) {
2208                        val = mMemWatchProcesses.get(procName, 0);
2209                    }
2210                    if (val != null) {
2211                        memLimit = val.first;
2212                        reportPackage = val.second;
2213                    } else {
2214                        memLimit = 0;
2215                        reportPackage = null;
2216                    }
2217                }
2218                if (procName == null) {
2219                    return;
2220                }
2221
2222                if (DEBUG_PSS) Slog.d(TAG_PSS,
2223                        "Showing dump heap notification from " + procName + "/" + uid);
2224
2225                INotificationManager inm = NotificationManager.getService();
2226                if (inm == null) {
2227                    return;
2228                }
2229
2230                String text = mContext.getString(R.string.dump_heap_notification, procName);
2231
2232
2233                Intent deleteIntent = new Intent();
2234                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2235                Intent intent = new Intent();
2236                intent.setClassName("android", DumpHeapActivity.class.getName());
2237                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2238                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2239                if (reportPackage != null) {
2240                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2241                }
2242                int userId = UserHandle.getUserId(uid);
2243                Notification notification = new Notification.Builder(mContext)
2244                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2245                        .setWhen(0)
2246                        .setOngoing(true)
2247                        .setAutoCancel(true)
2248                        .setTicker(text)
2249                        .setColor(mContext.getColor(
2250                                com.android.internal.R.color.system_notification_accent_color))
2251                        .setContentTitle(text)
2252                        .setContentText(
2253                                mContext.getText(R.string.dump_heap_notification_detail))
2254                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2255                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2256                                new UserHandle(userId)))
2257                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2258                                deleteIntent, 0, UserHandle.SYSTEM))
2259                        .build();
2260
2261                try {
2262                    int[] outId = new int[1];
2263                    inm.enqueueNotificationWithTag("android", "android", null,
2264                            R.string.dump_heap_notification,
2265                            notification, outId, userId);
2266                } catch (RuntimeException e) {
2267                    Slog.w(ActivityManagerService.TAG,
2268                            "Error showing notification for dump heap", e);
2269                } catch (RemoteException e) {
2270                }
2271            } break;
2272            case DELETE_DUMPHEAP_MSG: {
2273                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2274                        DumpHeapActivity.JAVA_URI,
2275                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2276                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2277                        UserHandle.myUserId());
2278                synchronized (ActivityManagerService.this) {
2279                    mMemWatchDumpFile = null;
2280                    mMemWatchDumpProcName = null;
2281                    mMemWatchDumpPid = -1;
2282                    mMemWatchDumpUid = -1;
2283                }
2284            } break;
2285            case FOREGROUND_PROFILE_CHANGED_MSG: {
2286                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2287            } break;
2288            case REPORT_TIME_TRACKER_MSG: {
2289                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2290                tracker.deliverResult(mContext);
2291            } break;
2292            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2293                mUserController.dispatchUserSwitchComplete(msg.arg1);
2294            } break;
2295            case REPORT_LOCKED_BOOT_COMPLETE_MSG: {
2296                mUserController.dispatchLockedBootComplete(msg.arg1);
2297            } break;
2298            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2299                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2300                try {
2301                    connection.shutdown();
2302                } catch (RemoteException e) {
2303                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2304                }
2305                // Only a UiAutomation can set this flag and now that
2306                // it is finished we make sure it is reset to its default.
2307                mUserIsMonkey = false;
2308            } break;
2309            case IDLE_UIDS_MSG: {
2310                idleUids();
2311            } break;
2312            case LOG_STACK_STATE: {
2313                synchronized (ActivityManagerService.this) {
2314                    mStackSupervisor.logStackState();
2315                }
2316            } break;
2317            case VR_MODE_CHANGE_MSG: {
2318                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2319                if (vrService == null) {
2320                    break;
2321                }
2322                final ActivityRecord r = (ActivityRecord) msg.obj;
2323                boolean vrMode;
2324                ComponentName requestedPackage;
2325                ComponentName callingPackage;
2326                int userId;
2327                synchronized (ActivityManagerService.this) {
2328                    vrMode = r.requestedVrComponent != null;
2329                    requestedPackage = r.requestedVrComponent;
2330                    userId = r.userId;
2331                    callingPackage = r.info.getComponentName();
2332                    if (mInVrMode != vrMode) {
2333                        mInVrMode = vrMode;
2334                        mShowDialogs = shouldShowDialogs(getGlobalConfiguration(), mInVrMode);
2335                        if (r.app != null) {
2336                            ProcessRecord proc = r.app;
2337                            if (proc.vrThreadTid > 0) {
2338                                if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
2339                                    try {
2340                                        if (mInVrMode == true) {
2341                                            Process.setThreadScheduler(proc.vrThreadTid,
2342                                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
2343                                        } else {
2344                                            Process.setThreadScheduler(proc.vrThreadTid,
2345                                                Process.SCHED_OTHER, 0);
2346                                        }
2347                                    } catch (IllegalArgumentException e) {
2348                                        Slog.w(TAG, "Failed to set scheduling policy, thread does"
2349                                                + " not exist:\n" + e);
2350                                    }
2351                                }
2352                            }
2353                        }
2354                    }
2355                }
2356                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2357            } break;
2358            case VR_MODE_APPLY_IF_NEEDED_MSG: {
2359                final ActivityRecord r = (ActivityRecord) msg.obj;
2360                final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2361                if (needsVrMode) {
2362                    applyVrMode(msg.arg1 == 1, r.requestedVrComponent, r.userId,
2363                            r.info.getComponentName(), false);
2364                }
2365            } break;
2366            case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
2367                synchronized (ActivityManagerService.this) {
2368                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2369                        ProcessRecord r = mLruProcesses.get(i);
2370                        if (r.thread != null) {
2371                            try {
2372                                r.thread.handleTrustStorageUpdate();
2373                            } catch (RemoteException ex) {
2374                                Slog.w(TAG, "Failed to handle trust storage update for: " +
2375                                        r.info.processName);
2376                            }
2377                        }
2378                    }
2379                }
2380            } break;
2381            }
2382        }
2383    };
2384
2385    static final int COLLECT_PSS_BG_MSG = 1;
2386
2387    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2388        @Override
2389        public void handleMessage(Message msg) {
2390            switch (msg.what) {
2391            case COLLECT_PSS_BG_MSG: {
2392                long start = SystemClock.uptimeMillis();
2393                MemInfoReader memInfo = null;
2394                synchronized (ActivityManagerService.this) {
2395                    if (mFullPssPending) {
2396                        mFullPssPending = false;
2397                        memInfo = new MemInfoReader();
2398                    }
2399                }
2400                if (memInfo != null) {
2401                    updateCpuStatsNow();
2402                    long nativeTotalPss = 0;
2403                    final List<ProcessCpuTracker.Stats> stats;
2404                    synchronized (mProcessCpuTracker) {
2405                        stats = mProcessCpuTracker.getStats( (st)-> {
2406                            return st.vsize > 0 && st.uid < Process.FIRST_APPLICATION_UID;
2407                        });
2408                    }
2409                    final int N = stats.size();
2410                    for (int j = 0; j < N; j++) {
2411                        synchronized (mPidsSelfLocked) {
2412                            if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2413                                // This is one of our own processes; skip it.
2414                                continue;
2415                            }
2416                        }
2417                        nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2418                    }
2419                    memInfo.readMemInfo();
2420                    synchronized (ActivityManagerService.this) {
2421                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2422                                + (SystemClock.uptimeMillis()-start) + "ms");
2423                        final long cachedKb = memInfo.getCachedSizeKb();
2424                        final long freeKb = memInfo.getFreeSizeKb();
2425                        final long zramKb = memInfo.getZramTotalSizeKb();
2426                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2427                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2428                                kernelKb*1024, nativeTotalPss*1024);
2429                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2430                                nativeTotalPss);
2431                    }
2432                }
2433
2434                int num = 0;
2435                long[] tmp = new long[2];
2436                do {
2437                    ProcessRecord proc;
2438                    int procState;
2439                    int pid;
2440                    long lastPssTime;
2441                    synchronized (ActivityManagerService.this) {
2442                        if (mPendingPssProcesses.size() <= 0) {
2443                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2444                                    "Collected PSS of " + num + " processes in "
2445                                    + (SystemClock.uptimeMillis() - start) + "ms");
2446                            mPendingPssProcesses.clear();
2447                            return;
2448                        }
2449                        proc = mPendingPssProcesses.remove(0);
2450                        procState = proc.pssProcState;
2451                        lastPssTime = proc.lastPssTime;
2452                        if (proc.thread != null && procState == proc.setProcState
2453                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2454                                        < SystemClock.uptimeMillis()) {
2455                            pid = proc.pid;
2456                        } else {
2457                            proc = null;
2458                            pid = 0;
2459                        }
2460                    }
2461                    if (proc != null) {
2462                        long pss = Debug.getPss(pid, tmp, null);
2463                        synchronized (ActivityManagerService.this) {
2464                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2465                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2466                                num++;
2467                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2468                                        SystemClock.uptimeMillis());
2469                            }
2470                        }
2471                    }
2472                } while (true);
2473            }
2474            }
2475        }
2476    };
2477
2478    public void setSystemProcess() {
2479        try {
2480            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2481            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2482            ServiceManager.addService("meminfo", new MemBinder(this));
2483            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2484            ServiceManager.addService("dbinfo", new DbBinder(this));
2485            if (MONITOR_CPU_USAGE) {
2486                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2487            }
2488            ServiceManager.addService("permission", new PermissionController(this));
2489            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2490
2491            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2492                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2493            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2494
2495            synchronized (this) {
2496                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2497                app.persistent = true;
2498                app.pid = MY_PID;
2499                app.maxAdj = ProcessList.SYSTEM_ADJ;
2500                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2501                synchronized (mPidsSelfLocked) {
2502                    mPidsSelfLocked.put(app.pid, app);
2503                }
2504                updateLruProcessLocked(app, false, null);
2505                updateOomAdjLocked();
2506            }
2507        } catch (PackageManager.NameNotFoundException e) {
2508            throw new RuntimeException(
2509                    "Unable to find android system package", e);
2510        }
2511    }
2512
2513    public void setWindowManager(WindowManagerService wm) {
2514        mWindowManager = wm;
2515        mStackSupervisor.setWindowManager(wm);
2516        mActivityStarter.setWindowManager(wm);
2517    }
2518
2519    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2520        mUsageStatsService = usageStatsManager;
2521    }
2522
2523    public void startObservingNativeCrashes() {
2524        final NativeCrashListener ncl = new NativeCrashListener(this);
2525        ncl.start();
2526    }
2527
2528    public IAppOpsService getAppOpsService() {
2529        return mAppOpsService;
2530    }
2531
2532    static class MemBinder extends Binder {
2533        ActivityManagerService mActivityManagerService;
2534        MemBinder(ActivityManagerService activityManagerService) {
2535            mActivityManagerService = activityManagerService;
2536        }
2537
2538        @Override
2539        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2540            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2541                    != PackageManager.PERMISSION_GRANTED) {
2542                pw.println("Permission Denial: can't dump meminfo from from pid="
2543                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2544                        + " without permission " + android.Manifest.permission.DUMP);
2545                return;
2546            }
2547
2548            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2549        }
2550    }
2551
2552    static class GraphicsBinder extends Binder {
2553        ActivityManagerService mActivityManagerService;
2554        GraphicsBinder(ActivityManagerService activityManagerService) {
2555            mActivityManagerService = activityManagerService;
2556        }
2557
2558        @Override
2559        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2560            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2561                    != PackageManager.PERMISSION_GRANTED) {
2562                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2563                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2564                        + " without permission " + android.Manifest.permission.DUMP);
2565                return;
2566            }
2567
2568            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2569        }
2570    }
2571
2572    static class DbBinder extends Binder {
2573        ActivityManagerService mActivityManagerService;
2574        DbBinder(ActivityManagerService activityManagerService) {
2575            mActivityManagerService = activityManagerService;
2576        }
2577
2578        @Override
2579        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2580            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2581                    != PackageManager.PERMISSION_GRANTED) {
2582                pw.println("Permission Denial: can't dump dbinfo from from pid="
2583                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2584                        + " without permission " + android.Manifest.permission.DUMP);
2585                return;
2586            }
2587
2588            mActivityManagerService.dumpDbInfo(fd, pw, args);
2589        }
2590    }
2591
2592    static class CpuBinder extends Binder {
2593        ActivityManagerService mActivityManagerService;
2594        CpuBinder(ActivityManagerService activityManagerService) {
2595            mActivityManagerService = activityManagerService;
2596        }
2597
2598        @Override
2599        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2600            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2601                    != PackageManager.PERMISSION_GRANTED) {
2602                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2603                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2604                        + " without permission " + android.Manifest.permission.DUMP);
2605                return;
2606            }
2607
2608            synchronized (mActivityManagerService.mProcessCpuTracker) {
2609                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2610                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2611                        SystemClock.uptimeMillis()));
2612            }
2613        }
2614    }
2615
2616    public static final class Lifecycle extends SystemService {
2617        private final ActivityManagerService mService;
2618
2619        public Lifecycle(Context context) {
2620            super(context);
2621            mService = new ActivityManagerService(context);
2622        }
2623
2624        @Override
2625        public void onStart() {
2626            mService.start();
2627        }
2628
2629        public ActivityManagerService getService() {
2630            return mService;
2631        }
2632    }
2633
2634    // Note: This method is invoked on the main thread but may need to attach various
2635    // handlers to other threads.  So take care to be explicit about the looper.
2636    public ActivityManagerService(Context systemContext) {
2637        mContext = systemContext;
2638        mFactoryTest = FactoryTest.getMode();
2639        mSystemThread = ActivityThread.currentActivityThread();
2640
2641        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2642
2643        mPermissionReviewRequired = mContext.getResources().getBoolean(
2644                com.android.internal.R.bool.config_permissionReviewRequired);
2645
2646        mHandlerThread = new ServiceThread(TAG,
2647                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2648        mHandlerThread.start();
2649        mHandler = new MainHandler(mHandlerThread.getLooper());
2650        mUiHandler = new UiHandler();
2651
2652        /* static; one-time init here */
2653        if (sKillHandler == null) {
2654            sKillThread = new ServiceThread(TAG + ":kill",
2655                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2656            sKillThread.start();
2657            sKillHandler = new KillHandler(sKillThread.getLooper());
2658        }
2659
2660        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2661                "foreground", BROADCAST_FG_TIMEOUT, false);
2662        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2663                "background", BROADCAST_BG_TIMEOUT, true);
2664        mBroadcastQueues[0] = mFgBroadcastQueue;
2665        mBroadcastQueues[1] = mBgBroadcastQueue;
2666
2667        mServices = new ActiveServices(this);
2668        mProviderMap = new ProviderMap(this);
2669        mAppErrors = new AppErrors(mContext, this);
2670
2671        // TODO: Move creation of battery stats service outside of activity manager service.
2672        File dataDir = Environment.getDataDirectory();
2673        File systemDir = new File(dataDir, "system");
2674        systemDir.mkdirs();
2675        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2676        mBatteryStatsService.getActiveStatistics().readLocked();
2677        mBatteryStatsService.scheduleWriteToDisk();
2678        mOnBattery = DEBUG_POWER ? true
2679                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2680        mBatteryStatsService.getActiveStatistics().setCallback(this);
2681
2682        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2683
2684        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2685        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2686                new IAppOpsCallback.Stub() {
2687                    @Override public void opChanged(int op, int uid, String packageName) {
2688                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2689                            if (mAppOpsService.checkOperation(op, uid, packageName)
2690                                    != AppOpsManager.MODE_ALLOWED) {
2691                                runInBackgroundDisabled(uid);
2692                            }
2693                        }
2694                    }
2695                });
2696
2697        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2698
2699        mUserController = new UserController(this);
2700
2701        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2702            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2703
2704        if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2705            mUseFifoUiScheduling = true;
2706        }
2707
2708        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2709
2710        mTempGlobalConfig.setToDefaults();
2711        mTempGlobalConfig.setLocales(LocaleList.getDefault());
2712        mConfigurationSeq = mTempGlobalConfig.seq = 1;
2713
2714        mProcessCpuTracker.init();
2715
2716        mStackSupervisor = new ActivityStackSupervisor(this);
2717        mStackSupervisor.onConfigurationChanged(mTempGlobalConfig);
2718        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2719        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2720        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2721        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2722
2723        mProcessCpuThread = new Thread("CpuTracker") {
2724            @Override
2725            public void run() {
2726                while (true) {
2727                    try {
2728                        try {
2729                            synchronized(this) {
2730                                final long now = SystemClock.uptimeMillis();
2731                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2732                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2733                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2734                                //        + ", write delay=" + nextWriteDelay);
2735                                if (nextWriteDelay < nextCpuDelay) {
2736                                    nextCpuDelay = nextWriteDelay;
2737                                }
2738                                if (nextCpuDelay > 0) {
2739                                    mProcessCpuMutexFree.set(true);
2740                                    this.wait(nextCpuDelay);
2741                                }
2742                            }
2743                        } catch (InterruptedException e) {
2744                        }
2745                        updateCpuStatsNow();
2746                    } catch (Exception e) {
2747                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2748                    }
2749                }
2750            }
2751        };
2752
2753        Watchdog.getInstance().addMonitor(this);
2754        Watchdog.getInstance().addThread(mHandler);
2755    }
2756
2757    public void setSystemServiceManager(SystemServiceManager mgr) {
2758        mSystemServiceManager = mgr;
2759    }
2760
2761    public void setInstaller(Installer installer) {
2762        mInstaller = installer;
2763    }
2764
2765    private void start() {
2766        Process.removeAllProcessGroups();
2767        mProcessCpuThread.start();
2768
2769        mBatteryStatsService.publish(mContext);
2770        mAppOpsService.publish(mContext);
2771        Slog.d("AppOps", "AppOpsService published");
2772        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2773    }
2774
2775    void onUserStoppedLocked(int userId) {
2776        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2777    }
2778
2779    public void initPowerManagement() {
2780        mStackSupervisor.initPowerManagement();
2781        mBatteryStatsService.initPowerManagement();
2782        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2783        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2784        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2785        mVoiceWakeLock.setReferenceCounted(false);
2786    }
2787
2788    @Override
2789    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2790            throws RemoteException {
2791        if (code == SYSPROPS_TRANSACTION) {
2792            // We need to tell all apps about the system property change.
2793            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2794            synchronized(this) {
2795                final int NP = mProcessNames.getMap().size();
2796                for (int ip=0; ip<NP; ip++) {
2797                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2798                    final int NA = apps.size();
2799                    for (int ia=0; ia<NA; ia++) {
2800                        ProcessRecord app = apps.valueAt(ia);
2801                        if (app.thread != null) {
2802                            procs.add(app.thread.asBinder());
2803                        }
2804                    }
2805                }
2806            }
2807
2808            int N = procs.size();
2809            for (int i=0; i<N; i++) {
2810                Parcel data2 = Parcel.obtain();
2811                try {
2812                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2813                } catch (RemoteException e) {
2814                }
2815                data2.recycle();
2816            }
2817        }
2818        try {
2819            return super.onTransact(code, data, reply, flags);
2820        } catch (RuntimeException e) {
2821            // The activity manager only throws security exceptions, so let's
2822            // log all others.
2823            if (!(e instanceof SecurityException)) {
2824                Slog.wtf(TAG, "Activity Manager Crash", e);
2825            }
2826            throw e;
2827        }
2828    }
2829
2830    void updateCpuStats() {
2831        final long now = SystemClock.uptimeMillis();
2832        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2833            return;
2834        }
2835        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2836            synchronized (mProcessCpuThread) {
2837                mProcessCpuThread.notify();
2838            }
2839        }
2840    }
2841
2842    void updateCpuStatsNow() {
2843        synchronized (mProcessCpuTracker) {
2844            mProcessCpuMutexFree.set(false);
2845            final long now = SystemClock.uptimeMillis();
2846            boolean haveNewCpuStats = false;
2847
2848            if (MONITOR_CPU_USAGE &&
2849                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2850                mLastCpuTime.set(now);
2851                mProcessCpuTracker.update();
2852                if (mProcessCpuTracker.hasGoodLastStats()) {
2853                    haveNewCpuStats = true;
2854                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2855                    //Slog.i(TAG, "Total CPU usage: "
2856                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2857
2858                    // Slog the cpu usage if the property is set.
2859                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2860                        int user = mProcessCpuTracker.getLastUserTime();
2861                        int system = mProcessCpuTracker.getLastSystemTime();
2862                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2863                        int irq = mProcessCpuTracker.getLastIrqTime();
2864                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2865                        int idle = mProcessCpuTracker.getLastIdleTime();
2866
2867                        int total = user + system + iowait + irq + softIrq + idle;
2868                        if (total == 0) total = 1;
2869
2870                        EventLog.writeEvent(EventLogTags.CPU,
2871                                ((user+system+iowait+irq+softIrq) * 100) / total,
2872                                (user * 100) / total,
2873                                (system * 100) / total,
2874                                (iowait * 100) / total,
2875                                (irq * 100) / total,
2876                                (softIrq * 100) / total);
2877                    }
2878                }
2879            }
2880
2881            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2882            synchronized(bstats) {
2883                synchronized(mPidsSelfLocked) {
2884                    if (haveNewCpuStats) {
2885                        if (bstats.startAddingCpuLocked()) {
2886                            int totalUTime = 0;
2887                            int totalSTime = 0;
2888                            final int N = mProcessCpuTracker.countStats();
2889                            for (int i=0; i<N; i++) {
2890                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2891                                if (!st.working) {
2892                                    continue;
2893                                }
2894                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2895                                totalUTime += st.rel_utime;
2896                                totalSTime += st.rel_stime;
2897                                if (pr != null) {
2898                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2899                                    if (ps == null || !ps.isActive()) {
2900                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2901                                                pr.info.uid, pr.processName);
2902                                    }
2903                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2904                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2905                                } else {
2906                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2907                                    if (ps == null || !ps.isActive()) {
2908                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2909                                                bstats.mapUid(st.uid), st.name);
2910                                    }
2911                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2912                                }
2913                            }
2914                            final int userTime = mProcessCpuTracker.getLastUserTime();
2915                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2916                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2917                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2918                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2919                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2920                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2921                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2922                        }
2923                    }
2924                }
2925
2926                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2927                    mLastWriteTime = now;
2928                    mBatteryStatsService.scheduleWriteToDisk();
2929                }
2930            }
2931        }
2932    }
2933
2934    @Override
2935    public void batteryNeedsCpuUpdate() {
2936        updateCpuStatsNow();
2937    }
2938
2939    @Override
2940    public void batteryPowerChanged(boolean onBattery) {
2941        // When plugging in, update the CPU stats first before changing
2942        // the plug state.
2943        updateCpuStatsNow();
2944        synchronized (this) {
2945            synchronized(mPidsSelfLocked) {
2946                mOnBattery = DEBUG_POWER ? true : onBattery;
2947            }
2948        }
2949    }
2950
2951    @Override
2952    public void batterySendBroadcast(Intent intent) {
2953        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2954                AppOpsManager.OP_NONE, null, false, false,
2955                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2956    }
2957
2958    /**
2959     * Initialize the application bind args. These are passed to each
2960     * process when the bindApplication() IPC is sent to the process. They're
2961     * lazily setup to make sure the services are running when they're asked for.
2962     */
2963    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2964        // Isolated processes won't get this optimization, so that we don't
2965        // violate the rules about which services they have access to.
2966        if (isolated) {
2967            if (mIsolatedAppBindArgs == null) {
2968                mIsolatedAppBindArgs = new HashMap<>();
2969                mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
2970            }
2971            return mIsolatedAppBindArgs;
2972        }
2973
2974        if (mAppBindArgs == null) {
2975            mAppBindArgs = new HashMap<>();
2976
2977            // Setup the application init args
2978            mAppBindArgs.put("package", ServiceManager.getService("package"));
2979            mAppBindArgs.put("window", ServiceManager.getService("window"));
2980            mAppBindArgs.put(Context.ALARM_SERVICE,
2981                    ServiceManager.getService(Context.ALARM_SERVICE));
2982        }
2983        return mAppBindArgs;
2984    }
2985
2986    /**
2987     * Update AMS states when an activity is resumed. This should only be called by
2988     * {@link ActivityStack#setResumedActivityLocked} when an activity is resumed.
2989     */
2990    void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
2991        if (r.task.isApplicationTask()) {
2992            if (mCurAppTimeTracker != r.appTimeTracker) {
2993                // We are switching app tracking.  Complete the current one.
2994                if (mCurAppTimeTracker != null) {
2995                    mCurAppTimeTracker.stop();
2996                    mHandler.obtainMessage(
2997                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2998                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2999                    mCurAppTimeTracker = null;
3000                }
3001                if (r.appTimeTracker != null) {
3002                    mCurAppTimeTracker = r.appTimeTracker;
3003                    startTimeTrackingFocusedActivityLocked();
3004                }
3005            } else {
3006                startTimeTrackingFocusedActivityLocked();
3007            }
3008        } else {
3009            r.appTimeTracker = null;
3010        }
3011        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3012        // TODO: Probably not, because we don't want to resume voice on switching
3013        // back to this activity
3014        if (r.task.voiceInteractor != null) {
3015            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
3016        } else {
3017            finishRunningVoiceLocked();
3018            IVoiceInteractionSession session;
3019            if (mLastResumedActivity != null
3020                    && ((session = mLastResumedActivity.task.voiceSession) != null
3021                    || (session = mLastResumedActivity.voiceSession) != null)) {
3022                // We had been in a voice interaction session, but now focused has
3023                // move to something different.  Just finish the session, we can't
3024                // return to it and retain the proper state and synchronization with
3025                // the voice interaction service.
3026                finishVoiceTask(session);
3027            }
3028        }
3029
3030        mWindowManager.setFocusedApp(r.appToken, true);
3031
3032        applyUpdateLockStateLocked(r);
3033        applyUpdateVrModeLocked(r);
3034        if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
3035            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3036            mHandler.obtainMessage(
3037                    FOREGROUND_PROFILE_CHANGED_MSG, r.userId, 0).sendToTarget();
3038        }
3039
3040        mLastResumedActivity = r;
3041
3042        EventLogTags.writeAmSetResumedActivity(
3043                r == null ? -1 : r.userId,
3044                r == null ? "NULL" : r.shortComponentName,
3045                reason);
3046    }
3047
3048    @Override
3049    public void setFocusedStack(int stackId) {
3050        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3051        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3052        final long callingId = Binder.clearCallingIdentity();
3053        try {
3054            synchronized (this) {
3055                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3056                if (stack == null) {
3057                    return;
3058                }
3059                final ActivityRecord r = stack.topRunningActivityLocked();
3060                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
3061                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3062                }
3063            }
3064        } finally {
3065            Binder.restoreCallingIdentity(callingId);
3066        }
3067    }
3068
3069    @Override
3070    public void setFocusedTask(int taskId) {
3071        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3072        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3073        final long callingId = Binder.clearCallingIdentity();
3074        try {
3075            synchronized (this) {
3076                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3077                if (task == null) {
3078                    return;
3079                }
3080                final ActivityRecord r = task.topRunningActivityLocked();
3081                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
3082                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3083                }
3084            }
3085        } finally {
3086            Binder.restoreCallingIdentity(callingId);
3087        }
3088    }
3089
3090    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3091    @Override
3092    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3093        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3094        synchronized (this) {
3095            if (listener != null) {
3096                mTaskStackListeners.register(listener);
3097            }
3098        }
3099    }
3100
3101    @Override
3102    public void notifyActivityDrawn(IBinder token) {
3103        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3104        synchronized (this) {
3105            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3106            if (r != null) {
3107                r.getStack().notifyActivityDrawnLocked(r);
3108            }
3109        }
3110    }
3111
3112    final void applyUpdateLockStateLocked(ActivityRecord r) {
3113        // Modifications to the UpdateLock state are done on our handler, outside
3114        // the activity manager's locks.  The new state is determined based on the
3115        // state *now* of the relevant activity record.  The object is passed to
3116        // the handler solely for logging detail, not to be consulted/modified.
3117        final boolean nextState = r != null && r.immersive;
3118        mHandler.sendMessage(
3119                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3120    }
3121
3122    final void applyUpdateVrModeLocked(ActivityRecord r) {
3123        mHandler.sendMessage(
3124                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3125    }
3126
3127    private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3128        mHandler.sendMessage(
3129                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3130    }
3131
3132    private void applyVrMode(boolean enabled, ComponentName packageName, int userId,
3133            ComponentName callingPackage, boolean immediate) {
3134        VrManagerInternal vrService =
3135                LocalServices.getService(VrManagerInternal.class);
3136        if (immediate) {
3137            vrService.setVrModeImmediate(enabled, packageName, userId, callingPackage);
3138        } else {
3139            vrService.setVrMode(enabled, packageName, userId, callingPackage);
3140        }
3141    }
3142
3143    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3144        Message msg = Message.obtain();
3145        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3146        msg.obj = r.task.askedCompatMode ? null : r;
3147        mUiHandler.sendMessage(msg);
3148    }
3149
3150    final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3151        final Configuration globalConfig = getGlobalConfiguration();
3152        if (globalConfig.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3153                && r.appInfo.requiresSmallestWidthDp > globalConfig.smallestScreenWidthDp) {
3154            final Message msg = Message.obtain();
3155            msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3156            msg.obj = r;
3157            mUiHandler.sendMessage(msg);
3158        }
3159    }
3160
3161    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3162            String what, Object obj, ProcessRecord srcApp) {
3163        app.lastActivityTime = now;
3164
3165        if (app.activities.size() > 0) {
3166            // Don't want to touch dependent processes that are hosting activities.
3167            return index;
3168        }
3169
3170        int lrui = mLruProcesses.lastIndexOf(app);
3171        if (lrui < 0) {
3172            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3173                    + what + " " + obj + " from " + srcApp);
3174            return index;
3175        }
3176
3177        if (lrui >= index) {
3178            // Don't want to cause this to move dependent processes *back* in the
3179            // list as if they were less frequently used.
3180            return index;
3181        }
3182
3183        if (lrui >= mLruProcessActivityStart) {
3184            // Don't want to touch dependent processes that are hosting activities.
3185            return index;
3186        }
3187
3188        mLruProcesses.remove(lrui);
3189        if (index > 0) {
3190            index--;
3191        }
3192        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3193                + " in LRU list: " + app);
3194        mLruProcesses.add(index, app);
3195        return index;
3196    }
3197
3198    static void killProcessGroup(int uid, int pid) {
3199        if (sKillHandler != null) {
3200            sKillHandler.sendMessage(
3201                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3202        } else {
3203            Slog.w(TAG, "Asked to kill process group before system bringup!");
3204            Process.killProcessGroup(uid, pid);
3205        }
3206    }
3207
3208    final void removeLruProcessLocked(ProcessRecord app) {
3209        int lrui = mLruProcesses.lastIndexOf(app);
3210        if (lrui >= 0) {
3211            if (!app.killed) {
3212                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3213                Process.killProcessQuiet(app.pid);
3214                killProcessGroup(app.uid, app.pid);
3215            }
3216            if (lrui <= mLruProcessActivityStart) {
3217                mLruProcessActivityStart--;
3218            }
3219            if (lrui <= mLruProcessServiceStart) {
3220                mLruProcessServiceStart--;
3221            }
3222            mLruProcesses.remove(lrui);
3223        }
3224    }
3225
3226    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3227            ProcessRecord client) {
3228        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3229                || app.treatLikeActivity;
3230        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3231        if (!activityChange && hasActivity) {
3232            // The process has activities, so we are only allowing activity-based adjustments
3233            // to move it.  It should be kept in the front of the list with other
3234            // processes that have activities, and we don't want those to change their
3235            // order except due to activity operations.
3236            return;
3237        }
3238
3239        mLruSeq++;
3240        final long now = SystemClock.uptimeMillis();
3241        app.lastActivityTime = now;
3242
3243        // First a quick reject: if the app is already at the position we will
3244        // put it, then there is nothing to do.
3245        if (hasActivity) {
3246            final int N = mLruProcesses.size();
3247            if (N > 0 && mLruProcesses.get(N-1) == app) {
3248                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3249                return;
3250            }
3251        } else {
3252            if (mLruProcessServiceStart > 0
3253                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3254                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3255                return;
3256            }
3257        }
3258
3259        int lrui = mLruProcesses.lastIndexOf(app);
3260
3261        if (app.persistent && lrui >= 0) {
3262            // We don't care about the position of persistent processes, as long as
3263            // they are in the list.
3264            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3265            return;
3266        }
3267
3268        /* In progress: compute new position first, so we can avoid doing work
3269           if the process is not actually going to move.  Not yet working.
3270        int addIndex;
3271        int nextIndex;
3272        boolean inActivity = false, inService = false;
3273        if (hasActivity) {
3274            // Process has activities, put it at the very tipsy-top.
3275            addIndex = mLruProcesses.size();
3276            nextIndex = mLruProcessServiceStart;
3277            inActivity = true;
3278        } else if (hasService) {
3279            // Process has services, put it at the top of the service list.
3280            addIndex = mLruProcessActivityStart;
3281            nextIndex = mLruProcessServiceStart;
3282            inActivity = true;
3283            inService = true;
3284        } else  {
3285            // Process not otherwise of interest, it goes to the top of the non-service area.
3286            addIndex = mLruProcessServiceStart;
3287            if (client != null) {
3288                int clientIndex = mLruProcesses.lastIndexOf(client);
3289                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3290                        + app);
3291                if (clientIndex >= 0 && addIndex > clientIndex) {
3292                    addIndex = clientIndex;
3293                }
3294            }
3295            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3296        }
3297
3298        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3299                + mLruProcessActivityStart + "): " + app);
3300        */
3301
3302        if (lrui >= 0) {
3303            if (lrui < mLruProcessActivityStart) {
3304                mLruProcessActivityStart--;
3305            }
3306            if (lrui < mLruProcessServiceStart) {
3307                mLruProcessServiceStart--;
3308            }
3309            /*
3310            if (addIndex > lrui) {
3311                addIndex--;
3312            }
3313            if (nextIndex > lrui) {
3314                nextIndex--;
3315            }
3316            */
3317            mLruProcesses.remove(lrui);
3318        }
3319
3320        /*
3321        mLruProcesses.add(addIndex, app);
3322        if (inActivity) {
3323            mLruProcessActivityStart++;
3324        }
3325        if (inService) {
3326            mLruProcessActivityStart++;
3327        }
3328        */
3329
3330        int nextIndex;
3331        if (hasActivity) {
3332            final int N = mLruProcesses.size();
3333            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3334                // Process doesn't have activities, but has clients with
3335                // activities...  move it up, but one below the top (the top
3336                // should always have a real activity).
3337                if (DEBUG_LRU) Slog.d(TAG_LRU,
3338                        "Adding to second-top of LRU activity list: " + app);
3339                mLruProcesses.add(N - 1, app);
3340                // To keep it from spamming the LRU list (by making a bunch of clients),
3341                // we will push down any other entries owned by the app.
3342                final int uid = app.info.uid;
3343                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3344                    ProcessRecord subProc = mLruProcesses.get(i);
3345                    if (subProc.info.uid == uid) {
3346                        // We want to push this one down the list.  If the process after
3347                        // it is for the same uid, however, don't do so, because we don't
3348                        // want them internally to be re-ordered.
3349                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3350                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3351                                    "Pushing uid " + uid + " swapping at " + i + ": "
3352                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3353                            ProcessRecord tmp = mLruProcesses.get(i);
3354                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3355                            mLruProcesses.set(i - 1, tmp);
3356                            i--;
3357                        }
3358                    } else {
3359                        // A gap, we can stop here.
3360                        break;
3361                    }
3362                }
3363            } else {
3364                // Process has activities, put it at the very tipsy-top.
3365                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3366                mLruProcesses.add(app);
3367            }
3368            nextIndex = mLruProcessServiceStart;
3369        } else if (hasService) {
3370            // Process has services, put it at the top of the service list.
3371            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3372            mLruProcesses.add(mLruProcessActivityStart, app);
3373            nextIndex = mLruProcessServiceStart;
3374            mLruProcessActivityStart++;
3375        } else  {
3376            // Process not otherwise of interest, it goes to the top of the non-service area.
3377            int index = mLruProcessServiceStart;
3378            if (client != null) {
3379                // If there is a client, don't allow the process to be moved up higher
3380                // in the list than that client.
3381                int clientIndex = mLruProcesses.lastIndexOf(client);
3382                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3383                        + " when updating " + app);
3384                if (clientIndex <= lrui) {
3385                    // Don't allow the client index restriction to push it down farther in the
3386                    // list than it already is.
3387                    clientIndex = lrui;
3388                }
3389                if (clientIndex >= 0 && index > clientIndex) {
3390                    index = clientIndex;
3391                }
3392            }
3393            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3394            mLruProcesses.add(index, app);
3395            nextIndex = index-1;
3396            mLruProcessActivityStart++;
3397            mLruProcessServiceStart++;
3398        }
3399
3400        // If the app is currently using a content provider or service,
3401        // bump those processes as well.
3402        for (int j=app.connections.size()-1; j>=0; j--) {
3403            ConnectionRecord cr = app.connections.valueAt(j);
3404            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3405                    && cr.binding.service.app != null
3406                    && cr.binding.service.app.lruSeq != mLruSeq
3407                    && !cr.binding.service.app.persistent) {
3408                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3409                        "service connection", cr, app);
3410            }
3411        }
3412        for (int j=app.conProviders.size()-1; j>=0; j--) {
3413            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3414            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3415                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3416                        "provider reference", cpr, app);
3417            }
3418        }
3419    }
3420
3421    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3422        if (uid == Process.SYSTEM_UID) {
3423            // The system gets to run in any process.  If there are multiple
3424            // processes with the same uid, just pick the first (this
3425            // should never happen).
3426            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3427            if (procs == null) return null;
3428            final int procCount = procs.size();
3429            for (int i = 0; i < procCount; i++) {
3430                final int procUid = procs.keyAt(i);
3431                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3432                    // Don't use an app process or different user process for system component.
3433                    continue;
3434                }
3435                return procs.valueAt(i);
3436            }
3437        }
3438        ProcessRecord proc = mProcessNames.get(processName, uid);
3439        if (false && proc != null && !keepIfLarge
3440                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3441                && proc.lastCachedPss >= 4000) {
3442            // Turn this condition on to cause killing to happen regularly, for testing.
3443            if (proc.baseProcessTracker != null) {
3444                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3445            }
3446            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3447        } else if (proc != null && !keepIfLarge
3448                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3449                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3450            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3451            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3452                if (proc.baseProcessTracker != null) {
3453                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3454                }
3455                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3456            }
3457        }
3458        return proc;
3459    }
3460
3461    void notifyPackageUse(String packageName, int reason) {
3462        IPackageManager pm = AppGlobals.getPackageManager();
3463        try {
3464            pm.notifyPackageUse(packageName, reason);
3465        } catch (RemoteException e) {
3466        }
3467    }
3468
3469    boolean isNextTransitionForward() {
3470        int transit = mWindowManager.getPendingAppTransition();
3471        return transit == TRANSIT_ACTIVITY_OPEN
3472                || transit == TRANSIT_TASK_OPEN
3473                || transit == TRANSIT_TASK_TO_FRONT;
3474    }
3475
3476    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3477            String processName, String abiOverride, int uid, Runnable crashHandler) {
3478        synchronized(this) {
3479            ApplicationInfo info = new ApplicationInfo();
3480            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3481            // For isolated processes, the former contains the parent's uid and the latter the
3482            // actual uid of the isolated process.
3483            // In the special case introduced by this method (which is, starting an isolated
3484            // process directly from the SystemServer without an actual parent app process) the
3485            // closest thing to a parent's uid is SYSTEM_UID.
3486            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3487            // the |isolated| logic in the ProcessRecord constructor.
3488            info.uid = Process.SYSTEM_UID;
3489            info.processName = processName;
3490            info.className = entryPoint;
3491            info.packageName = "android";
3492            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3493                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3494                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3495                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3496                    crashHandler);
3497            return proc != null ? proc.pid : 0;
3498        }
3499    }
3500
3501    final ProcessRecord startProcessLocked(String processName,
3502            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3503            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3504            boolean isolated, boolean keepIfLarge) {
3505        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3506                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3507                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3508                null /* crashHandler */);
3509    }
3510
3511    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3512            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3513            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3514            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3515        long startTime = SystemClock.elapsedRealtime();
3516        ProcessRecord app;
3517        if (!isolated) {
3518            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3519            checkTime(startTime, "startProcess: after getProcessRecord");
3520
3521            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3522                // If we are in the background, then check to see if this process
3523                // is bad.  If so, we will just silently fail.
3524                if (mAppErrors.isBadProcessLocked(info)) {
3525                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3526                            + "/" + info.processName);
3527                    return null;
3528                }
3529            } else {
3530                // When the user is explicitly starting a process, then clear its
3531                // crash count so that we won't make it bad until they see at
3532                // least one crash dialog again, and make the process good again
3533                // if it had been bad.
3534                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3535                        + "/" + info.processName);
3536                mAppErrors.resetProcessCrashTimeLocked(info);
3537                if (mAppErrors.isBadProcessLocked(info)) {
3538                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3539                            UserHandle.getUserId(info.uid), info.uid,
3540                            info.processName);
3541                    mAppErrors.clearBadProcessLocked(info);
3542                    if (app != null) {
3543                        app.bad = false;
3544                    }
3545                }
3546            }
3547        } else {
3548            // If this is an isolated process, it can't re-use an existing process.
3549            app = null;
3550        }
3551
3552        // We don't have to do anything more if:
3553        // (1) There is an existing application record; and
3554        // (2) The caller doesn't think it is dead, OR there is no thread
3555        //     object attached to it so we know it couldn't have crashed; and
3556        // (3) There is a pid assigned to it, so it is either starting or
3557        //     already running.
3558        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3559                + " app=" + app + " knownToBeDead=" + knownToBeDead
3560                + " thread=" + (app != null ? app.thread : null)
3561                + " pid=" + (app != null ? app.pid : -1));
3562        if (app != null && app.pid > 0) {
3563            if ((!knownToBeDead && !app.killed) || app.thread == null) {
3564                // We already have the app running, or are waiting for it to
3565                // come up (we have a pid but not yet its thread), so keep it.
3566                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3567                // If this is a new package in the process, add the package to the list
3568                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3569                checkTime(startTime, "startProcess: done, added package to proc");
3570                return app;
3571            }
3572
3573            // An application record is attached to a previous process,
3574            // clean it up now.
3575            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3576            checkTime(startTime, "startProcess: bad proc running, killing");
3577            killProcessGroup(app.uid, app.pid);
3578            handleAppDiedLocked(app, true, true);
3579            checkTime(startTime, "startProcess: done killing old proc");
3580        }
3581
3582        String hostingNameStr = hostingName != null
3583                ? hostingName.flattenToShortString() : null;
3584
3585        if (app == null) {
3586            checkTime(startTime, "startProcess: creating new process record");
3587            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3588            if (app == null) {
3589                Slog.w(TAG, "Failed making new process record for "
3590                        + processName + "/" + info.uid + " isolated=" + isolated);
3591                return null;
3592            }
3593            app.crashHandler = crashHandler;
3594            checkTime(startTime, "startProcess: done creating new process record");
3595        } else {
3596            // If this is a new package in the process, add the package to the list
3597            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3598            checkTime(startTime, "startProcess: added package to existing proc");
3599        }
3600
3601        // If the system is not ready yet, then hold off on starting this
3602        // process until it is.
3603        if (!mProcessesReady
3604                && !isAllowedWhileBooting(info)
3605                && !allowWhileBooting) {
3606            if (!mProcessesOnHold.contains(app)) {
3607                mProcessesOnHold.add(app);
3608            }
3609            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3610                    "System not ready, putting on hold: " + app);
3611            checkTime(startTime, "startProcess: returning with proc on hold");
3612            return app;
3613        }
3614
3615        checkTime(startTime, "startProcess: stepping in to startProcess");
3616        startProcessLocked(
3617                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3618        checkTime(startTime, "startProcess: done starting proc!");
3619        return (app.pid != 0) ? app : null;
3620    }
3621
3622    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3623        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3624    }
3625
3626    private final void startProcessLocked(ProcessRecord app,
3627            String hostingType, String hostingNameStr) {
3628        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3629                null /* entryPoint */, null /* entryPointArgs */);
3630    }
3631
3632    private final void startProcessLocked(ProcessRecord app, String hostingType,
3633            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3634        long startTime = SystemClock.elapsedRealtime();
3635        if (app.pid > 0 && app.pid != MY_PID) {
3636            checkTime(startTime, "startProcess: removing from pids map");
3637            synchronized (mPidsSelfLocked) {
3638                mPidsSelfLocked.remove(app.pid);
3639                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3640            }
3641            checkTime(startTime, "startProcess: done removing from pids map");
3642            app.setPid(0);
3643        }
3644
3645        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3646                "startProcessLocked removing on hold: " + app);
3647        mProcessesOnHold.remove(app);
3648
3649        checkTime(startTime, "startProcess: starting to update cpu stats");
3650        updateCpuStats();
3651        checkTime(startTime, "startProcess: done updating cpu stats");
3652
3653        try {
3654            try {
3655                final int userId = UserHandle.getUserId(app.uid);
3656                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3657            } catch (RemoteException e) {
3658                throw e.rethrowAsRuntimeException();
3659            }
3660
3661            int uid = app.uid;
3662            int[] gids = null;
3663            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3664            if (!app.isolated) {
3665                int[] permGids = null;
3666                try {
3667                    checkTime(startTime, "startProcess: getting gids from package manager");
3668                    final IPackageManager pm = AppGlobals.getPackageManager();
3669                    permGids = pm.getPackageGids(app.info.packageName,
3670                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3671                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3672                            MountServiceInternal.class);
3673                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3674                            app.info.packageName);
3675                } catch (RemoteException e) {
3676                    throw e.rethrowAsRuntimeException();
3677                }
3678
3679                /*
3680                 * Add shared application and profile GIDs so applications can share some
3681                 * resources like shared libraries and access user-wide resources
3682                 */
3683                if (ArrayUtils.isEmpty(permGids)) {
3684                    gids = new int[2];
3685                } else {
3686                    gids = new int[permGids.length + 2];
3687                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3688                }
3689                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3690                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3691            }
3692            checkTime(startTime, "startProcess: building args");
3693            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3694                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3695                        && mTopComponent != null
3696                        && app.processName.equals(mTopComponent.getPackageName())) {
3697                    uid = 0;
3698                }
3699                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3700                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3701                    uid = 0;
3702                }
3703            }
3704            int debugFlags = 0;
3705            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3706                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3707                // Also turn on CheckJNI for debuggable apps. It's quite
3708                // awkward to turn on otherwise.
3709                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3710            }
3711            // Run the app in safe mode if its manifest requests so or the
3712            // system is booted in safe mode.
3713            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3714                mSafeMode == true) {
3715                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3716            }
3717            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3718                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3719            }
3720            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3721            if ("true".equals(genDebugInfoProperty)) {
3722                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3723            }
3724            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3725                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3726            }
3727            if ("1".equals(SystemProperties.get("debug.assert"))) {
3728                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3729            }
3730            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3731                // Enable all debug flags required by the native debugger.
3732                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3733                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3734                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3735                mNativeDebuggingApp = null;
3736            }
3737
3738            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3739            if (requiredAbi == null) {
3740                requiredAbi = Build.SUPPORTED_ABIS[0];
3741            }
3742
3743            String instructionSet = null;
3744            if (app.info.primaryCpuAbi != null) {
3745                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3746            }
3747
3748            app.gids = gids;
3749            app.requiredAbi = requiredAbi;
3750            app.instructionSet = instructionSet;
3751
3752            // Start the process.  It will either succeed and return a result containing
3753            // the PID of the new process, or else throw a RuntimeException.
3754            boolean isActivityProcess = (entryPoint == null);
3755            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3756            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3757                    app.processName);
3758            checkTime(startTime, "startProcess: asking zygote to start proc");
3759            Process.ProcessStartResult startResult = Process.start(entryPoint,
3760                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3761                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3762                    app.info.dataDir, entryPointArgs);
3763            checkTime(startTime, "startProcess: returned from zygote!");
3764            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3765
3766            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3767            checkTime(startTime, "startProcess: done updating battery stats");
3768
3769            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3770                    UserHandle.getUserId(uid), startResult.pid, uid,
3771                    app.processName, hostingType,
3772                    hostingNameStr != null ? hostingNameStr : "");
3773
3774            try {
3775                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3776                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3777            } catch (RemoteException ex) {
3778                // Ignore
3779            }
3780
3781            if (app.persistent) {
3782                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3783            }
3784
3785            checkTime(startTime, "startProcess: building log message");
3786            StringBuilder buf = mStringBuilder;
3787            buf.setLength(0);
3788            buf.append("Start proc ");
3789            buf.append(startResult.pid);
3790            buf.append(':');
3791            buf.append(app.processName);
3792            buf.append('/');
3793            UserHandle.formatUid(buf, uid);
3794            if (!isActivityProcess) {
3795                buf.append(" [");
3796                buf.append(entryPoint);
3797                buf.append("]");
3798            }
3799            buf.append(" for ");
3800            buf.append(hostingType);
3801            if (hostingNameStr != null) {
3802                buf.append(" ");
3803                buf.append(hostingNameStr);
3804            }
3805            Slog.i(TAG, buf.toString());
3806            app.setPid(startResult.pid);
3807            app.usingWrapper = startResult.usingWrapper;
3808            app.removed = false;
3809            app.killed = false;
3810            app.killedByAm = false;
3811            checkTime(startTime, "startProcess: starting to update pids map");
3812            ProcessRecord oldApp;
3813            synchronized (mPidsSelfLocked) {
3814                oldApp = mPidsSelfLocked.get(startResult.pid);
3815            }
3816            // If there is already an app occupying that pid that hasn't been cleaned up
3817            if (oldApp != null && !app.isolated) {
3818                // Clean up anything relating to this pid first
3819                Slog.w(TAG, "Reusing pid " + startResult.pid
3820                        + " while app is still mapped to it");
3821                cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3822                        true /*replacingPid*/);
3823            }
3824            synchronized (mPidsSelfLocked) {
3825                this.mPidsSelfLocked.put(startResult.pid, app);
3826                if (isActivityProcess) {
3827                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3828                    msg.obj = app;
3829                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3830                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3831                }
3832            }
3833            checkTime(startTime, "startProcess: done updating pids map");
3834        } catch (RuntimeException e) {
3835            Slog.e(TAG, "Failure starting process " + app.processName, e);
3836
3837            // Something went very wrong while trying to start this process; one
3838            // common case is when the package is frozen due to an active
3839            // upgrade. To recover, clean up any active bookkeeping related to
3840            // starting this process. (We already invoked this method once when
3841            // the package was initially frozen through KILL_APPLICATION_MSG, so
3842            // it doesn't hurt to use it again.)
3843            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3844                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3845        }
3846    }
3847
3848    void updateUsageStats(ActivityRecord component, boolean resumed) {
3849        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3850                "updateUsageStats: comp=" + component + "res=" + resumed);
3851        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3852        if (resumed) {
3853            if (mUsageStatsService != null) {
3854                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3855                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3856            }
3857            synchronized (stats) {
3858                stats.noteActivityResumedLocked(component.app.uid);
3859            }
3860        } else {
3861            if (mUsageStatsService != null) {
3862                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3863                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3864            }
3865            synchronized (stats) {
3866                stats.noteActivityPausedLocked(component.app.uid);
3867            }
3868        }
3869    }
3870
3871    Intent getHomeIntent() {
3872        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3873        intent.setComponent(mTopComponent);
3874        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3875        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3876            intent.addCategory(Intent.CATEGORY_HOME);
3877        }
3878        return intent;
3879    }
3880
3881    boolean startHomeActivityLocked(int userId, String reason) {
3882        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3883                && mTopAction == null) {
3884            // We are running in factory test mode, but unable to find
3885            // the factory test app, so just sit around displaying the
3886            // error message and don't try to start anything.
3887            return false;
3888        }
3889        Intent intent = getHomeIntent();
3890        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3891        if (aInfo != null) {
3892            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3893            // Don't do this if the home app is currently being
3894            // instrumented.
3895            aInfo = new ActivityInfo(aInfo);
3896            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3897            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3898                    aInfo.applicationInfo.uid, true);
3899            if (app == null || app.instrumentationClass == null) {
3900                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3901                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3902            }
3903        } else {
3904            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3905        }
3906
3907        return true;
3908    }
3909
3910    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3911        ActivityInfo ai = null;
3912        ComponentName comp = intent.getComponent();
3913        try {
3914            if (comp != null) {
3915                // Factory test.
3916                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3917            } else {
3918                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3919                        intent,
3920                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3921                        flags, userId);
3922
3923                if (info != null) {
3924                    ai = info.activityInfo;
3925                }
3926            }
3927        } catch (RemoteException e) {
3928            // ignore
3929        }
3930
3931        return ai;
3932    }
3933
3934    /**
3935     * Starts the "new version setup screen" if appropriate.
3936     */
3937    void startSetupActivityLocked() {
3938        // Only do this once per boot.
3939        if (mCheckedForSetup) {
3940            return;
3941        }
3942
3943        // We will show this screen if the current one is a different
3944        // version than the last one shown, and we are not running in
3945        // low-level factory test mode.
3946        final ContentResolver resolver = mContext.getContentResolver();
3947        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3948                Settings.Global.getInt(resolver,
3949                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3950            mCheckedForSetup = true;
3951
3952            // See if we should be showing the platform update setup UI.
3953            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3954            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3955                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3956            if (!ris.isEmpty()) {
3957                final ResolveInfo ri = ris.get(0);
3958                String vers = ri.activityInfo.metaData != null
3959                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3960                        : null;
3961                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3962                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3963                            Intent.METADATA_SETUP_VERSION);
3964                }
3965                String lastVers = Settings.Secure.getString(
3966                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3967                if (vers != null && !vers.equals(lastVers)) {
3968                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3969                    intent.setComponent(new ComponentName(
3970                            ri.activityInfo.packageName, ri.activityInfo.name));
3971                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3972                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3973                            null, 0, 0, 0, null, false, false, null, null, null);
3974                }
3975            }
3976        }
3977    }
3978
3979    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3980        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3981    }
3982
3983    void enforceNotIsolatedCaller(String caller) {
3984        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3985            throw new SecurityException("Isolated process not allowed to call " + caller);
3986        }
3987    }
3988
3989    void enforceShellRestriction(String restriction, int userHandle) {
3990        if (Binder.getCallingUid() == Process.SHELL_UID) {
3991            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3992                throw new SecurityException("Shell does not have permission to access user "
3993                        + userHandle);
3994            }
3995        }
3996    }
3997
3998    @Override
3999    public int getFrontActivityScreenCompatMode() {
4000        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4001        synchronized (this) {
4002            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4003        }
4004    }
4005
4006    @Override
4007    public void setFrontActivityScreenCompatMode(int mode) {
4008        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4009                "setFrontActivityScreenCompatMode");
4010        synchronized (this) {
4011            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4012        }
4013    }
4014
4015    @Override
4016    public int getPackageScreenCompatMode(String packageName) {
4017        enforceNotIsolatedCaller("getPackageScreenCompatMode");
4018        synchronized (this) {
4019            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4020        }
4021    }
4022
4023    @Override
4024    public void setPackageScreenCompatMode(String packageName, int mode) {
4025        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4026                "setPackageScreenCompatMode");
4027        synchronized (this) {
4028            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4029        }
4030    }
4031
4032    @Override
4033    public boolean getPackageAskScreenCompat(String packageName) {
4034        enforceNotIsolatedCaller("getPackageAskScreenCompat");
4035        synchronized (this) {
4036            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4037        }
4038    }
4039
4040    @Override
4041    public void setPackageAskScreenCompat(String packageName, boolean ask) {
4042        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4043                "setPackageAskScreenCompat");
4044        synchronized (this) {
4045            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4046        }
4047    }
4048
4049    private boolean hasUsageStatsPermission(String callingPackage) {
4050        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4051                Binder.getCallingUid(), callingPackage);
4052        if (mode == AppOpsManager.MODE_DEFAULT) {
4053            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4054                    == PackageManager.PERMISSION_GRANTED;
4055        }
4056        return mode == AppOpsManager.MODE_ALLOWED;
4057    }
4058
4059    @Override
4060    public int getPackageProcessState(String packageName, String callingPackage) {
4061        if (!hasUsageStatsPermission(callingPackage)) {
4062            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
4063                    "getPackageProcessState");
4064        }
4065
4066        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4067        synchronized (this) {
4068            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4069                final ProcessRecord proc = mLruProcesses.get(i);
4070                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4071                        || procState > proc.setProcState) {
4072                    boolean found = false;
4073                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4074                        if (proc.pkgList.keyAt(j).equals(packageName)) {
4075                            procState = proc.setProcState;
4076                            found = true;
4077                        }
4078                    }
4079                    if (proc.pkgDeps != null && !found) {
4080                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4081                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4082                                procState = proc.setProcState;
4083                                break;
4084                            }
4085                        }
4086                    }
4087                }
4088            }
4089        }
4090        return procState;
4091    }
4092
4093    @Override
4094    public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4095            throws RemoteException {
4096        synchronized (this) {
4097            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4098            if (app == null) {
4099                throw new IllegalArgumentException("Unknown process: " + process);
4100            }
4101            if (app.thread == null) {
4102                throw new IllegalArgumentException("Process has no app thread");
4103            }
4104            if (app.trimMemoryLevel >= level) {
4105                throw new IllegalArgumentException(
4106                        "Unable to set a higher trim level than current level");
4107            }
4108            if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4109                    app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4110                throw new IllegalArgumentException("Unable to set a background trim level "
4111                    + "on a foreground process");
4112            }
4113            app.thread.scheduleTrimMemory(level);
4114            app.trimMemoryLevel = level;
4115            return true;
4116        }
4117    }
4118
4119    private void dispatchProcessesChanged() {
4120        int N;
4121        synchronized (this) {
4122            N = mPendingProcessChanges.size();
4123            if (mActiveProcessChanges.length < N) {
4124                mActiveProcessChanges = new ProcessChangeItem[N];
4125            }
4126            mPendingProcessChanges.toArray(mActiveProcessChanges);
4127            mPendingProcessChanges.clear();
4128            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4129                    "*** Delivering " + N + " process changes");
4130        }
4131
4132        int i = mProcessObservers.beginBroadcast();
4133        while (i > 0) {
4134            i--;
4135            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4136            if (observer != null) {
4137                try {
4138                    for (int j=0; j<N; j++) {
4139                        ProcessChangeItem item = mActiveProcessChanges[j];
4140                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4141                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4142                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4143                                    + item.uid + ": " + item.foregroundActivities);
4144                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4145                                    item.foregroundActivities);
4146                        }
4147                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4148                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4149                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4150                                    + ": " + item.processState);
4151                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4152                        }
4153                    }
4154                } catch (RemoteException e) {
4155                }
4156            }
4157        }
4158        mProcessObservers.finishBroadcast();
4159
4160        synchronized (this) {
4161            for (int j=0; j<N; j++) {
4162                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4163            }
4164        }
4165    }
4166
4167    private void dispatchProcessDied(int pid, int uid) {
4168        int i = mProcessObservers.beginBroadcast();
4169        while (i > 0) {
4170            i--;
4171            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4172            if (observer != null) {
4173                try {
4174                    observer.onProcessDied(pid, uid);
4175                } catch (RemoteException e) {
4176                }
4177            }
4178        }
4179        mProcessObservers.finishBroadcast();
4180    }
4181
4182    private void dispatchUidsChanged() {
4183        int N;
4184        synchronized (this) {
4185            N = mPendingUidChanges.size();
4186            if (mActiveUidChanges.length < N) {
4187                mActiveUidChanges = new UidRecord.ChangeItem[N];
4188            }
4189            for (int i=0; i<N; i++) {
4190                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4191                mActiveUidChanges[i] = change;
4192                if (change.uidRecord != null) {
4193                    change.uidRecord.pendingChange = null;
4194                    change.uidRecord = null;
4195                }
4196            }
4197            mPendingUidChanges.clear();
4198            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4199                    "*** Delivering " + N + " uid changes");
4200        }
4201
4202        if (mLocalPowerManager != null) {
4203            for (int j=0; j<N; j++) {
4204                UidRecord.ChangeItem item = mActiveUidChanges[j];
4205                if (item.change == UidRecord.CHANGE_GONE
4206                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4207                    mLocalPowerManager.uidGone(item.uid);
4208                } else {
4209                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4210                }
4211            }
4212        }
4213
4214        int i = mUidObservers.beginBroadcast();
4215        while (i > 0) {
4216            i--;
4217            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4218            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4219            if (observer != null) {
4220                try {
4221                    for (int j=0; j<N; j++) {
4222                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4223                        final int change = item.change;
4224                        UidRecord validateUid = null;
4225                        if (VALIDATE_UID_STATES && i == 0) {
4226                            validateUid = mValidateUids.get(item.uid);
4227                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4228                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4229                                validateUid = new UidRecord(item.uid);
4230                                mValidateUids.put(item.uid, validateUid);
4231                            }
4232                        }
4233                        if (change == UidRecord.CHANGE_IDLE
4234                                || change == UidRecord.CHANGE_GONE_IDLE) {
4235                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4236                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4237                                        "UID idle uid=" + item.uid);
4238                                observer.onUidIdle(item.uid);
4239                            }
4240                            if (VALIDATE_UID_STATES && i == 0) {
4241                                if (validateUid != null) {
4242                                    validateUid.idle = true;
4243                                }
4244                            }
4245                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4246                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4247                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4248                                        "UID active uid=" + item.uid);
4249                                observer.onUidActive(item.uid);
4250                            }
4251                            if (VALIDATE_UID_STATES && i == 0) {
4252                                validateUid.idle = false;
4253                            }
4254                        }
4255                        if (change == UidRecord.CHANGE_GONE
4256                                || change == UidRecord.CHANGE_GONE_IDLE) {
4257                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4258                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4259                                        "UID gone uid=" + item.uid);
4260                                observer.onUidGone(item.uid);
4261                            }
4262                            if (VALIDATE_UID_STATES && i == 0) {
4263                                if (validateUid != null) {
4264                                    mValidateUids.remove(item.uid);
4265                                }
4266                            }
4267                        } else {
4268                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4269                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4270                                        "UID CHANGED uid=" + item.uid
4271                                                + ": " + item.processState);
4272                                observer.onUidStateChanged(item.uid, item.processState);
4273                            }
4274                            if (VALIDATE_UID_STATES && i == 0) {
4275                                validateUid.curProcState = validateUid.setProcState
4276                                        = item.processState;
4277                            }
4278                        }
4279                    }
4280                } catch (RemoteException e) {
4281                }
4282            }
4283        }
4284        mUidObservers.finishBroadcast();
4285
4286        synchronized (this) {
4287            for (int j=0; j<N; j++) {
4288                mAvailUidChanges.add(mActiveUidChanges[j]);
4289            }
4290        }
4291    }
4292
4293    @Override
4294    public final int startActivity(IApplicationThread caller, String callingPackage,
4295            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4296            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4297        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4298                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4299                UserHandle.getCallingUserId());
4300    }
4301
4302    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4303        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4304        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4305                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4306                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4307
4308        // TODO: Switch to user app stacks here.
4309        String mimeType = intent.getType();
4310        final Uri data = intent.getData();
4311        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4312            mimeType = getProviderMimeType(data, userId);
4313        }
4314        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4315
4316        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4317        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4318                null, 0, 0, null, null, null, null, false, userId, container, null);
4319    }
4320
4321    @Override
4322    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4323            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4324            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4325        enforceNotIsolatedCaller("startActivity");
4326        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4327                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4328        // TODO: Switch to user app stacks here.
4329        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4330                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4331                profilerInfo, null, null, bOptions, false, userId, null, null);
4332    }
4333
4334    @Override
4335    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4336            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4337            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4338            int userId) {
4339
4340        // This is very dangerous -- it allows you to perform a start activity (including
4341        // permission grants) as any app that may launch one of your own activities.  So
4342        // we will only allow this to be done from activities that are part of the core framework,
4343        // and then only when they are running as the system.
4344        final ActivityRecord sourceRecord;
4345        final int targetUid;
4346        final String targetPackage;
4347        synchronized (this) {
4348            if (resultTo == null) {
4349                throw new SecurityException("Must be called from an activity");
4350            }
4351            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4352            if (sourceRecord == null) {
4353                throw new SecurityException("Called with bad activity token: " + resultTo);
4354            }
4355            if (!sourceRecord.info.packageName.equals("android")) {
4356                throw new SecurityException(
4357                        "Must be called from an activity that is declared in the android package");
4358            }
4359            if (sourceRecord.app == null) {
4360                throw new SecurityException("Called without a process attached to activity");
4361            }
4362            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4363                // This is still okay, as long as this activity is running under the
4364                // uid of the original calling activity.
4365                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4366                    throw new SecurityException(
4367                            "Calling activity in uid " + sourceRecord.app.uid
4368                                    + " must be system uid or original calling uid "
4369                                    + sourceRecord.launchedFromUid);
4370                }
4371            }
4372            if (ignoreTargetSecurity) {
4373                if (intent.getComponent() == null) {
4374                    throw new SecurityException(
4375                            "Component must be specified with ignoreTargetSecurity");
4376                }
4377                if (intent.getSelector() != null) {
4378                    throw new SecurityException(
4379                            "Selector not allowed with ignoreTargetSecurity");
4380                }
4381            }
4382            targetUid = sourceRecord.launchedFromUid;
4383            targetPackage = sourceRecord.launchedFromPackage;
4384        }
4385
4386        if (userId == UserHandle.USER_NULL) {
4387            userId = UserHandle.getUserId(sourceRecord.app.uid);
4388        }
4389
4390        // TODO: Switch to user app stacks here.
4391        try {
4392            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4393                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4394                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4395            return ret;
4396        } catch (SecurityException e) {
4397            // XXX need to figure out how to propagate to original app.
4398            // A SecurityException here is generally actually a fault of the original
4399            // calling activity (such as a fairly granting permissions), so propagate it
4400            // back to them.
4401            /*
4402            StringBuilder msg = new StringBuilder();
4403            msg.append("While launching");
4404            msg.append(intent.toString());
4405            msg.append(": ");
4406            msg.append(e.getMessage());
4407            */
4408            throw e;
4409        }
4410    }
4411
4412    @Override
4413    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4414            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4415            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4416        enforceNotIsolatedCaller("startActivityAndWait");
4417        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4418                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4419        WaitResult res = new WaitResult();
4420        // TODO: Switch to user app stacks here.
4421        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4422                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4423                bOptions, false, userId, null, null);
4424        return res;
4425    }
4426
4427    @Override
4428    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4429            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4430            int startFlags, Configuration config, Bundle bOptions, int userId) {
4431        enforceNotIsolatedCaller("startActivityWithConfig");
4432        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4433                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4434        // TODO: Switch to user app stacks here.
4435        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4436                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4437                null, null, config, bOptions, false, userId, null, null);
4438        return ret;
4439    }
4440
4441    @Override
4442    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4443            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4444            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4445            throws TransactionTooLargeException {
4446        enforceNotIsolatedCaller("startActivityIntentSender");
4447        // Refuse possible leaked file descriptors
4448        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4449            throw new IllegalArgumentException("File descriptors passed in Intent");
4450        }
4451
4452        IIntentSender sender = intent.getTarget();
4453        if (!(sender instanceof PendingIntentRecord)) {
4454            throw new IllegalArgumentException("Bad PendingIntent object");
4455        }
4456
4457        PendingIntentRecord pir = (PendingIntentRecord)sender;
4458
4459        synchronized (this) {
4460            // If this is coming from the currently resumed activity, it is
4461            // effectively saying that app switches are allowed at this point.
4462            final ActivityStack stack = getFocusedStack();
4463            if (stack.mResumedActivity != null &&
4464                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4465                mAppSwitchesAllowedTime = 0;
4466            }
4467        }
4468        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4469                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4470        return ret;
4471    }
4472
4473    @Override
4474    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4475            Intent intent, String resolvedType, IVoiceInteractionSession session,
4476            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4477            Bundle bOptions, int userId) {
4478        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4479                != PackageManager.PERMISSION_GRANTED) {
4480            String msg = "Permission Denial: startVoiceActivity() from pid="
4481                    + Binder.getCallingPid()
4482                    + ", uid=" + Binder.getCallingUid()
4483                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4484            Slog.w(TAG, msg);
4485            throw new SecurityException(msg);
4486        }
4487        if (session == null || interactor == null) {
4488            throw new NullPointerException("null session or interactor");
4489        }
4490        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4491                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4492        // TODO: Switch to user app stacks here.
4493        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4494                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4495                null, bOptions, false, userId, null, null);
4496    }
4497
4498    @Override
4499    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4500            throws RemoteException {
4501        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4502        synchronized (this) {
4503            ActivityRecord activity = getFocusedStack().topActivity();
4504            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4505                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4506            }
4507            if (mRunningVoice != null || activity.task.voiceSession != null
4508                    || activity.voiceSession != null) {
4509                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4510                return;
4511            }
4512            if (activity.pendingVoiceInteractionStart) {
4513                Slog.w(TAG, "Pending start of voice interaction already.");
4514                return;
4515            }
4516            activity.pendingVoiceInteractionStart = true;
4517        }
4518        LocalServices.getService(VoiceInteractionManagerInternal.class)
4519                .startLocalVoiceInteraction(callingActivity, options);
4520    }
4521
4522    @Override
4523    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4524        LocalServices.getService(VoiceInteractionManagerInternal.class)
4525                .stopLocalVoiceInteraction(callingActivity);
4526    }
4527
4528    @Override
4529    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4530        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4531                .supportsLocalVoiceInteraction();
4532    }
4533
4534    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4535            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4536        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4537        if (activityToCallback == null) return;
4538        activityToCallback.setVoiceSessionLocked(voiceSession);
4539
4540        // Inform the activity
4541        try {
4542            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4543                    voiceInteractor);
4544            long token = Binder.clearCallingIdentity();
4545            try {
4546                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4547            } finally {
4548                Binder.restoreCallingIdentity(token);
4549            }
4550            // TODO: VI Should we cache the activity so that it's easier to find later
4551            // rather than scan through all the stacks and activities?
4552        } catch (RemoteException re) {
4553            activityToCallback.clearVoiceSessionLocked();
4554            // TODO: VI Should this terminate the voice session?
4555        }
4556    }
4557
4558    @Override
4559    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4560        synchronized (this) {
4561            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4562                if (keepAwake) {
4563                    mVoiceWakeLock.acquire();
4564                } else {
4565                    mVoiceWakeLock.release();
4566                }
4567            }
4568        }
4569    }
4570
4571    @Override
4572    public boolean startNextMatchingActivity(IBinder callingActivity,
4573            Intent intent, Bundle bOptions) {
4574        // Refuse possible leaked file descriptors
4575        if (intent != null && intent.hasFileDescriptors() == true) {
4576            throw new IllegalArgumentException("File descriptors passed in Intent");
4577        }
4578        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4579
4580        synchronized (this) {
4581            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4582            if (r == null) {
4583                ActivityOptions.abort(options);
4584                return false;
4585            }
4586            if (r.app == null || r.app.thread == null) {
4587                // The caller is not running...  d'oh!
4588                ActivityOptions.abort(options);
4589                return false;
4590            }
4591            intent = new Intent(intent);
4592            // The caller is not allowed to change the data.
4593            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4594            // And we are resetting to find the next component...
4595            intent.setComponent(null);
4596
4597            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4598
4599            ActivityInfo aInfo = null;
4600            try {
4601                List<ResolveInfo> resolves =
4602                    AppGlobals.getPackageManager().queryIntentActivities(
4603                            intent, r.resolvedType,
4604                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4605                            UserHandle.getCallingUserId()).getList();
4606
4607                // Look for the original activity in the list...
4608                final int N = resolves != null ? resolves.size() : 0;
4609                for (int i=0; i<N; i++) {
4610                    ResolveInfo rInfo = resolves.get(i);
4611                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4612                            && rInfo.activityInfo.name.equals(r.info.name)) {
4613                        // We found the current one...  the next matching is
4614                        // after it.
4615                        i++;
4616                        if (i<N) {
4617                            aInfo = resolves.get(i).activityInfo;
4618                        }
4619                        if (debug) {
4620                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4621                                    + "/" + r.info.name);
4622                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4623                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4624                        }
4625                        break;
4626                    }
4627                }
4628            } catch (RemoteException e) {
4629            }
4630
4631            if (aInfo == null) {
4632                // Nobody who is next!
4633                ActivityOptions.abort(options);
4634                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4635                return false;
4636            }
4637
4638            intent.setComponent(new ComponentName(
4639                    aInfo.applicationInfo.packageName, aInfo.name));
4640            intent.setFlags(intent.getFlags()&~(
4641                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4642                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4643                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4644                    Intent.FLAG_ACTIVITY_NEW_TASK));
4645
4646            // Okay now we need to start the new activity, replacing the
4647            // currently running activity.  This is a little tricky because
4648            // we want to start the new one as if the current one is finished,
4649            // but not finish the current one first so that there is no flicker.
4650            // And thus...
4651            final boolean wasFinishing = r.finishing;
4652            r.finishing = true;
4653
4654            // Propagate reply information over to the new activity.
4655            final ActivityRecord resultTo = r.resultTo;
4656            final String resultWho = r.resultWho;
4657            final int requestCode = r.requestCode;
4658            r.resultTo = null;
4659            if (resultTo != null) {
4660                resultTo.removeResultsLocked(r, resultWho, requestCode);
4661            }
4662
4663            final long origId = Binder.clearCallingIdentity();
4664            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4665                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4666                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4667                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4668                    false, false, null, null, null);
4669            Binder.restoreCallingIdentity(origId);
4670
4671            r.finishing = wasFinishing;
4672            if (res != ActivityManager.START_SUCCESS) {
4673                return false;
4674            }
4675            return true;
4676        }
4677    }
4678
4679    @Override
4680    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4681        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4682            String msg = "Permission Denial: startActivityFromRecents called without " +
4683                    START_TASKS_FROM_RECENTS;
4684            Slog.w(TAG, msg);
4685            throw new SecurityException(msg);
4686        }
4687        final long origId = Binder.clearCallingIdentity();
4688        try {
4689            synchronized (this) {
4690                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4691            }
4692        } finally {
4693            Binder.restoreCallingIdentity(origId);
4694        }
4695    }
4696
4697    final int startActivityInPackage(int uid, String callingPackage,
4698            Intent intent, String resolvedType, IBinder resultTo,
4699            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4700            IActivityContainer container, TaskRecord inTask) {
4701
4702        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4703                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4704
4705        // TODO: Switch to user app stacks here.
4706        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4707                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4708                null, null, null, bOptions, false, userId, container, inTask);
4709        return ret;
4710    }
4711
4712    @Override
4713    public final int startActivities(IApplicationThread caller, String callingPackage,
4714            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4715            int userId) {
4716        enforceNotIsolatedCaller("startActivities");
4717        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4718                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4719        // TODO: Switch to user app stacks here.
4720        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4721                resolvedTypes, resultTo, bOptions, userId);
4722        return ret;
4723    }
4724
4725    final int startActivitiesInPackage(int uid, String callingPackage,
4726            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4727            Bundle bOptions, int userId) {
4728
4729        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4730                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4731        // TODO: Switch to user app stacks here.
4732        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4733                resultTo, bOptions, userId);
4734        return ret;
4735    }
4736
4737    @Override
4738    public void reportActivityFullyDrawn(IBinder token) {
4739        synchronized (this) {
4740            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4741            if (r == null) {
4742                return;
4743            }
4744            r.reportFullyDrawnLocked();
4745        }
4746    }
4747
4748    @Override
4749    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4750        synchronized (this) {
4751            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4752            if (r == null) {
4753                return;
4754            }
4755            TaskRecord task = r.task;
4756            if (task != null && (!task.mFullscreen || !task.getStack().mFullscreen)) {
4757                // Fixed screen orientation isn't supported when activities aren't in full screen
4758                // mode.
4759                return;
4760            }
4761            final long origId = Binder.clearCallingIdentity();
4762            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4763            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4764                    getGlobalConfiguration(), r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4765            if (config != null) {
4766                r.frozenBeforeDestroy = true;
4767                if (!updateConfigurationLocked(config, r, false)) {
4768                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4769                }
4770            }
4771            Binder.restoreCallingIdentity(origId);
4772        }
4773    }
4774
4775    @Override
4776    public int getRequestedOrientation(IBinder token) {
4777        synchronized (this) {
4778            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4779            if (r == null) {
4780                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4781            }
4782            return mWindowManager.getAppOrientation(r.appToken);
4783        }
4784    }
4785
4786    @Override
4787    public final void requestActivityRelaunch(IBinder token) {
4788        synchronized(this) {
4789            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4790            if (r == null) {
4791                return;
4792            }
4793            final long origId = Binder.clearCallingIdentity();
4794            try {
4795                r.forceNewConfig = true;
4796                r.getStack().ensureActivityConfigurationLocked(r, 0, false);
4797            } finally {
4798                Binder.restoreCallingIdentity(origId);
4799            }
4800        }
4801    }
4802
4803    /**
4804     * This is the internal entry point for handling Activity.finish().
4805     *
4806     * @param token The Binder token referencing the Activity we want to finish.
4807     * @param resultCode Result code, if any, from this Activity.
4808     * @param resultData Result data (Intent), if any, from this Activity.
4809     * @param finishTask Whether to finish the task associated with this Activity.
4810     *
4811     * @return Returns true if the activity successfully finished, or false if it is still running.
4812     */
4813    @Override
4814    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4815            int finishTask) {
4816        // Refuse possible leaked file descriptors
4817        if (resultData != null && resultData.hasFileDescriptors() == true) {
4818            throw new IllegalArgumentException("File descriptors passed in Intent");
4819        }
4820
4821        synchronized(this) {
4822            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4823            if (r == null) {
4824                return true;
4825            }
4826            // Keep track of the root activity of the task before we finish it
4827            TaskRecord tr = r.task;
4828            ActivityRecord rootR = tr.getRootActivity();
4829            if (rootR == null) {
4830                Slog.w(TAG, "Finishing task with all activities already finished");
4831            }
4832            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4833            // finish.
4834            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4835                    mStackSupervisor.isLastLockedTask(tr)) {
4836                Slog.i(TAG, "Not finishing task in lock task mode");
4837                mStackSupervisor.showLockTaskToast();
4838                return false;
4839            }
4840            if (mController != null) {
4841                // Find the first activity that is not finishing.
4842                ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
4843                if (next != null) {
4844                    // ask watcher if this is allowed
4845                    boolean resumeOK = true;
4846                    try {
4847                        resumeOK = mController.activityResuming(next.packageName);
4848                    } catch (RemoteException e) {
4849                        mController = null;
4850                        Watchdog.getInstance().setActivityController(null);
4851                    }
4852
4853                    if (!resumeOK) {
4854                        Slog.i(TAG, "Not finishing activity because controller resumed");
4855                        return false;
4856                    }
4857                }
4858            }
4859            final long origId = Binder.clearCallingIdentity();
4860            try {
4861                boolean res;
4862                final boolean finishWithRootActivity =
4863                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4864                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4865                        || (finishWithRootActivity && r == rootR)) {
4866                    // If requested, remove the task that is associated to this activity only if it
4867                    // was the root activity in the task. The result code and data is ignored
4868                    // because we don't support returning them across task boundaries. Also, to
4869                    // keep backwards compatibility we remove the task from recents when finishing
4870                    // task with root activity.
4871                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4872                    if (!res) {
4873                        Slog.i(TAG, "Removing task failed to finish activity");
4874                    }
4875                } else {
4876                    res = tr.getStack().requestFinishActivityLocked(token, resultCode,
4877                            resultData, "app-request", true);
4878                    if (!res) {
4879                        Slog.i(TAG, "Failed to finish by app-request");
4880                    }
4881                }
4882                return res;
4883            } finally {
4884                Binder.restoreCallingIdentity(origId);
4885            }
4886        }
4887    }
4888
4889    @Override
4890    public final void finishHeavyWeightApp() {
4891        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4892                != PackageManager.PERMISSION_GRANTED) {
4893            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4894                    + Binder.getCallingPid()
4895                    + ", uid=" + Binder.getCallingUid()
4896                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4897            Slog.w(TAG, msg);
4898            throw new SecurityException(msg);
4899        }
4900
4901        synchronized(this) {
4902            if (mHeavyWeightProcess == null) {
4903                return;
4904            }
4905
4906            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4907            for (int i = 0; i < activities.size(); i++) {
4908                ActivityRecord r = activities.get(i);
4909                if (!r.finishing && r.isInStackLocked()) {
4910                    r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
4911                            null, "finish-heavy", true);
4912                }
4913            }
4914
4915            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4916                    mHeavyWeightProcess.userId, 0));
4917            mHeavyWeightProcess = null;
4918        }
4919    }
4920
4921    @Override
4922    public void crashApplication(int uid, int initialPid, String packageName,
4923            String message) {
4924        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4925                != PackageManager.PERMISSION_GRANTED) {
4926            String msg = "Permission Denial: crashApplication() from pid="
4927                    + Binder.getCallingPid()
4928                    + ", uid=" + Binder.getCallingUid()
4929                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4930            Slog.w(TAG, msg);
4931            throw new SecurityException(msg);
4932        }
4933
4934        synchronized(this) {
4935            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4936        }
4937    }
4938
4939    @Override
4940    public final void finishSubActivity(IBinder token, String resultWho,
4941            int requestCode) {
4942        synchronized(this) {
4943            final long origId = Binder.clearCallingIdentity();
4944            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4945            if (r != null) {
4946                r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
4947            }
4948            Binder.restoreCallingIdentity(origId);
4949        }
4950    }
4951
4952    @Override
4953    public boolean finishActivityAffinity(IBinder token) {
4954        synchronized(this) {
4955            final long origId = Binder.clearCallingIdentity();
4956            try {
4957                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4958                if (r == null) {
4959                    return false;
4960                }
4961
4962                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4963                // can finish.
4964                final TaskRecord task = r.task;
4965                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4966                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4967                    mStackSupervisor.showLockTaskToast();
4968                    return false;
4969                }
4970                return task.getStack().finishActivityAffinityLocked(r);
4971            } finally {
4972                Binder.restoreCallingIdentity(origId);
4973            }
4974        }
4975    }
4976
4977    @Override
4978    public void finishVoiceTask(IVoiceInteractionSession session) {
4979        synchronized (this) {
4980            final long origId = Binder.clearCallingIdentity();
4981            try {
4982                // TODO: VI Consider treating local voice interactions and voice tasks
4983                // differently here
4984                mStackSupervisor.finishVoiceTask(session);
4985            } finally {
4986                Binder.restoreCallingIdentity(origId);
4987            }
4988        }
4989
4990    }
4991
4992    @Override
4993    public boolean releaseActivityInstance(IBinder token) {
4994        synchronized(this) {
4995            final long origId = Binder.clearCallingIdentity();
4996            try {
4997                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4998                if (r == null) {
4999                    return false;
5000                }
5001                return r.getStack().safelyDestroyActivityLocked(r, "app-req");
5002            } finally {
5003                Binder.restoreCallingIdentity(origId);
5004            }
5005        }
5006    }
5007
5008    @Override
5009    public void releaseSomeActivities(IApplicationThread appInt) {
5010        synchronized(this) {
5011            final long origId = Binder.clearCallingIdentity();
5012            try {
5013                ProcessRecord app = getRecordForAppLocked(appInt);
5014                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5015            } finally {
5016                Binder.restoreCallingIdentity(origId);
5017            }
5018        }
5019    }
5020
5021    @Override
5022    public boolean willActivityBeVisible(IBinder token) {
5023        synchronized(this) {
5024            ActivityStack stack = ActivityRecord.getStackLocked(token);
5025            if (stack != null) {
5026                return stack.willActivityBeVisibleLocked(token);
5027            }
5028            return false;
5029        }
5030    }
5031
5032    @Override
5033    public void overridePendingTransition(IBinder token, String packageName,
5034            int enterAnim, int exitAnim) {
5035        synchronized(this) {
5036            ActivityRecord self = ActivityRecord.isInStackLocked(token);
5037            if (self == null) {
5038                return;
5039            }
5040
5041            final long origId = Binder.clearCallingIdentity();
5042
5043            if (self.state == ActivityState.RESUMED
5044                    || self.state == ActivityState.PAUSING) {
5045                mWindowManager.overridePendingAppTransition(packageName,
5046                        enterAnim, exitAnim, null);
5047            }
5048
5049            Binder.restoreCallingIdentity(origId);
5050        }
5051    }
5052
5053    /**
5054     * Main function for removing an existing process from the activity manager
5055     * as a result of that process going away.  Clears out all connections
5056     * to the process.
5057     */
5058    private final void handleAppDiedLocked(ProcessRecord app,
5059            boolean restarting, boolean allowRestart) {
5060        int pid = app.pid;
5061        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5062                false /*replacingPid*/);
5063        if (!kept && !restarting) {
5064            removeLruProcessLocked(app);
5065            if (pid > 0) {
5066                ProcessList.remove(pid);
5067            }
5068        }
5069
5070        if (mProfileProc == app) {
5071            clearProfilerLocked();
5072        }
5073
5074        // Remove this application's activities from active lists.
5075        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5076
5077        app.activities.clear();
5078
5079        if (app.instrumentationClass != null) {
5080            Slog.w(TAG, "Crash of app " + app.processName
5081                  + " running instrumentation " + app.instrumentationClass);
5082            Bundle info = new Bundle();
5083            info.putString("shortMsg", "Process crashed.");
5084            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5085        }
5086
5087        if (!restarting && hasVisibleActivities
5088                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5089            // If there was nothing to resume, and we are not already restarting this process, but
5090            // there is a visible activity that is hosted by the process...  then make sure all
5091            // visible activities are running, taking care of restarting this process.
5092            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5093        }
5094    }
5095
5096    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5097        IBinder threadBinder = thread.asBinder();
5098        // Find the application record.
5099        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5100            ProcessRecord rec = mLruProcesses.get(i);
5101            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5102                return i;
5103            }
5104        }
5105        return -1;
5106    }
5107
5108    final ProcessRecord getRecordForAppLocked(
5109            IApplicationThread thread) {
5110        if (thread == null) {
5111            return null;
5112        }
5113
5114        int appIndex = getLRURecordIndexForAppLocked(thread);
5115        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5116    }
5117
5118    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5119        // If there are no longer any background processes running,
5120        // and the app that died was not running instrumentation,
5121        // then tell everyone we are now low on memory.
5122        boolean haveBg = false;
5123        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5124            ProcessRecord rec = mLruProcesses.get(i);
5125            if (rec.thread != null
5126                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5127                haveBg = true;
5128                break;
5129            }
5130        }
5131
5132        if (!haveBg) {
5133            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5134            if (doReport) {
5135                long now = SystemClock.uptimeMillis();
5136                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5137                    doReport = false;
5138                } else {
5139                    mLastMemUsageReportTime = now;
5140                }
5141            }
5142            final ArrayList<ProcessMemInfo> memInfos
5143                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5144            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5145            long now = SystemClock.uptimeMillis();
5146            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5147                ProcessRecord rec = mLruProcesses.get(i);
5148                if (rec == dyingProc || rec.thread == null) {
5149                    continue;
5150                }
5151                if (doReport) {
5152                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5153                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5154                }
5155                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5156                    // The low memory report is overriding any current
5157                    // state for a GC request.  Make sure to do
5158                    // heavy/important/visible/foreground processes first.
5159                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5160                        rec.lastRequestedGc = 0;
5161                    } else {
5162                        rec.lastRequestedGc = rec.lastLowMemory;
5163                    }
5164                    rec.reportLowMemory = true;
5165                    rec.lastLowMemory = now;
5166                    mProcessesToGc.remove(rec);
5167                    addProcessToGcListLocked(rec);
5168                }
5169            }
5170            if (doReport) {
5171                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5172                mHandler.sendMessage(msg);
5173            }
5174            scheduleAppGcsLocked();
5175        }
5176    }
5177
5178    final void appDiedLocked(ProcessRecord app) {
5179       appDiedLocked(app, app.pid, app.thread, false);
5180    }
5181
5182    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5183            boolean fromBinderDied) {
5184        // First check if this ProcessRecord is actually active for the pid.
5185        synchronized (mPidsSelfLocked) {
5186            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5187            if (curProc != app) {
5188                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5189                return;
5190            }
5191        }
5192
5193        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5194        synchronized (stats) {
5195            stats.noteProcessDiedLocked(app.info.uid, pid);
5196        }
5197
5198        if (!app.killed) {
5199            if (!fromBinderDied) {
5200                Process.killProcessQuiet(pid);
5201            }
5202            killProcessGroup(app.uid, pid);
5203            app.killed = true;
5204        }
5205
5206        // Clean up already done if the process has been re-started.
5207        if (app.pid == pid && app.thread != null &&
5208                app.thread.asBinder() == thread.asBinder()) {
5209            boolean doLowMem = app.instrumentationClass == null;
5210            boolean doOomAdj = doLowMem;
5211            if (!app.killedByAm) {
5212                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5213                        + ") has died");
5214                mAllowLowerMemLevel = true;
5215            } else {
5216                // Note that we always want to do oom adj to update our state with the
5217                // new number of procs.
5218                mAllowLowerMemLevel = false;
5219                doLowMem = false;
5220            }
5221            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5222            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5223                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5224            handleAppDiedLocked(app, false, true);
5225
5226            if (doOomAdj) {
5227                updateOomAdjLocked();
5228            }
5229            if (doLowMem) {
5230                doLowMemReportIfNeededLocked(app);
5231            }
5232        } else if (app.pid != pid) {
5233            // A new process has already been started.
5234            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5235                    + ") has died and restarted (pid " + app.pid + ").");
5236            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5237        } else if (DEBUG_PROCESSES) {
5238            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5239                    + thread.asBinder());
5240        }
5241    }
5242
5243    /**
5244     * If a stack trace dump file is configured, dump process stack traces.
5245     * @param clearTraces causes the dump file to be erased prior to the new
5246     *    traces being written, if true; when false, the new traces will be
5247     *    appended to any existing file content.
5248     * @param firstPids of dalvik VM processes to dump stack traces for first
5249     * @param lastPids of dalvik VM processes to dump stack traces for last
5250     * @param nativeProcs optional list of native process names to dump stack crawls
5251     * @return file containing stack traces, or null if no dump file is configured
5252     */
5253    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5254            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5255        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5256        if (tracesPath == null || tracesPath.length() == 0) {
5257            return null;
5258        }
5259
5260        File tracesFile = new File(tracesPath);
5261        try {
5262            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5263            tracesFile.createNewFile();
5264            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5265        } catch (IOException e) {
5266            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5267            return null;
5268        }
5269
5270        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5271        return tracesFile;
5272    }
5273
5274    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5275            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5276        // Use a FileObserver to detect when traces finish writing.
5277        // The order of traces is considered important to maintain for legibility.
5278        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5279            @Override
5280            public synchronized void onEvent(int event, String path) { notify(); }
5281        };
5282
5283        try {
5284            observer.startWatching();
5285
5286            // First collect all of the stacks of the most important pids.
5287            if (firstPids != null) {
5288                try {
5289                    int num = firstPids.size();
5290                    for (int i = 0; i < num; i++) {
5291                        synchronized (observer) {
5292                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5293                                    + firstPids.get(i));
5294                            final long sime = SystemClock.elapsedRealtime();
5295                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5296                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5297                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5298                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5299                        }
5300                    }
5301                } catch (InterruptedException e) {
5302                    Slog.wtf(TAG, e);
5303                }
5304            }
5305
5306            // Next collect the stacks of the native pids
5307            if (nativeProcs != null) {
5308                int[] pids = Process.getPidsForCommands(nativeProcs);
5309                if (pids != null) {
5310                    for (int pid : pids) {
5311                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5312                        final long sime = SystemClock.elapsedRealtime();
5313                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5314                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5315                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5316                    }
5317                }
5318            }
5319
5320            // Lastly, measure CPU usage.
5321            if (processCpuTracker != null) {
5322                processCpuTracker.init();
5323                System.gc();
5324                processCpuTracker.update();
5325                try {
5326                    synchronized (processCpuTracker) {
5327                        processCpuTracker.wait(500); // measure over 1/2 second.
5328                    }
5329                } catch (InterruptedException e) {
5330                }
5331                processCpuTracker.update();
5332
5333                // We'll take the stack crawls of just the top apps using CPU.
5334                final int N = processCpuTracker.countWorkingStats();
5335                int numProcs = 0;
5336                for (int i=0; i<N && numProcs<5; i++) {
5337                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5338                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5339                        numProcs++;
5340                        try {
5341                            synchronized (observer) {
5342                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5343                                        + stats.pid);
5344                                final long stime = SystemClock.elapsedRealtime();
5345                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5346                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5347                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5348                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5349                            }
5350                        } catch (InterruptedException e) {
5351                            Slog.wtf(TAG, e);
5352                        }
5353                    } else if (DEBUG_ANR) {
5354                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5355                                + stats.pid);
5356                    }
5357                }
5358            }
5359        } finally {
5360            observer.stopWatching();
5361        }
5362    }
5363
5364    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5365        if (true || IS_USER_BUILD) {
5366            return;
5367        }
5368        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5369        if (tracesPath == null || tracesPath.length() == 0) {
5370            return;
5371        }
5372
5373        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5374        StrictMode.allowThreadDiskWrites();
5375        try {
5376            final File tracesFile = new File(tracesPath);
5377            final File tracesDir = tracesFile.getParentFile();
5378            final File tracesTmp = new File(tracesDir, "__tmp__");
5379            try {
5380                if (tracesFile.exists()) {
5381                    tracesTmp.delete();
5382                    tracesFile.renameTo(tracesTmp);
5383                }
5384                StringBuilder sb = new StringBuilder();
5385                Time tobj = new Time();
5386                tobj.set(System.currentTimeMillis());
5387                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5388                sb.append(": ");
5389                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5390                sb.append(" since ");
5391                sb.append(msg);
5392                FileOutputStream fos = new FileOutputStream(tracesFile);
5393                fos.write(sb.toString().getBytes());
5394                if (app == null) {
5395                    fos.write("\n*** No application process!".getBytes());
5396                }
5397                fos.close();
5398                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5399            } catch (IOException e) {
5400                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5401                return;
5402            }
5403
5404            if (app != null) {
5405                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5406                firstPids.add(app.pid);
5407                dumpStackTraces(tracesPath, firstPids, null, null, null);
5408            }
5409
5410            File lastTracesFile = null;
5411            File curTracesFile = null;
5412            for (int i=9; i>=0; i--) {
5413                String name = String.format(Locale.US, "slow%02d.txt", i);
5414                curTracesFile = new File(tracesDir, name);
5415                if (curTracesFile.exists()) {
5416                    if (lastTracesFile != null) {
5417                        curTracesFile.renameTo(lastTracesFile);
5418                    } else {
5419                        curTracesFile.delete();
5420                    }
5421                }
5422                lastTracesFile = curTracesFile;
5423            }
5424            tracesFile.renameTo(curTracesFile);
5425            if (tracesTmp.exists()) {
5426                tracesTmp.renameTo(tracesFile);
5427            }
5428        } finally {
5429            StrictMode.setThreadPolicy(oldPolicy);
5430        }
5431    }
5432
5433    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5434        if (!mLaunchWarningShown) {
5435            mLaunchWarningShown = true;
5436            mUiHandler.post(new Runnable() {
5437                @Override
5438                public void run() {
5439                    synchronized (ActivityManagerService.this) {
5440                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5441                        d.show();
5442                        mUiHandler.postDelayed(new Runnable() {
5443                            @Override
5444                            public void run() {
5445                                synchronized (ActivityManagerService.this) {
5446                                    d.dismiss();
5447                                    mLaunchWarningShown = false;
5448                                }
5449                            }
5450                        }, 4000);
5451                    }
5452                }
5453            });
5454        }
5455    }
5456
5457    @Override
5458    public boolean clearApplicationUserData(final String packageName,
5459            final IPackageDataObserver observer, int userId) {
5460        enforceNotIsolatedCaller("clearApplicationUserData");
5461        int uid = Binder.getCallingUid();
5462        int pid = Binder.getCallingPid();
5463        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5464                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5465
5466
5467        long callingId = Binder.clearCallingIdentity();
5468        try {
5469            IPackageManager pm = AppGlobals.getPackageManager();
5470            int pkgUid = -1;
5471            synchronized(this) {
5472                if (getPackageManagerInternalLocked().isPackageDataProtected(
5473                        userId, packageName)) {
5474                    throw new SecurityException(
5475                            "Cannot clear data for a protected package: " + packageName);
5476                }
5477
5478                try {
5479                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5480                } catch (RemoteException e) {
5481                }
5482                if (pkgUid == -1) {
5483                    Slog.w(TAG, "Invalid packageName: " + packageName);
5484                    if (observer != null) {
5485                        try {
5486                            observer.onRemoveCompleted(packageName, false);
5487                        } catch (RemoteException e) {
5488                            Slog.i(TAG, "Observer no longer exists.");
5489                        }
5490                    }
5491                    return false;
5492                }
5493                if (uid == pkgUid || checkComponentPermission(
5494                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5495                        pid, uid, -1, true)
5496                        == PackageManager.PERMISSION_GRANTED) {
5497                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5498                } else {
5499                    throw new SecurityException("PID " + pid + " does not have permission "
5500                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5501                                    + " of package " + packageName);
5502                }
5503
5504                // Remove all tasks match the cleared application package and user
5505                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5506                    final TaskRecord tr = mRecentTasks.get(i);
5507                    final String taskPackageName =
5508                            tr.getBaseIntent().getComponent().getPackageName();
5509                    if (tr.userId != userId) continue;
5510                    if (!taskPackageName.equals(packageName)) continue;
5511                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5512                }
5513            }
5514
5515            final int pkgUidF = pkgUid;
5516            final int userIdF = userId;
5517            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5518                @Override
5519                public void onRemoveCompleted(String packageName, boolean succeeded)
5520                        throws RemoteException {
5521                    synchronized (ActivityManagerService.this) {
5522                        finishForceStopPackageLocked(packageName, pkgUidF);
5523                    }
5524
5525                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5526                            Uri.fromParts("package", packageName, null));
5527                    intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5528                    intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5529                    broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5530                            null, null, 0, null, null, null, null, false, false, userIdF);
5531
5532                    if (observer != null) {
5533                        observer.onRemoveCompleted(packageName, succeeded);
5534                    }
5535                }
5536            };
5537
5538            try {
5539                // Clear application user data
5540                pm.clearApplicationUserData(packageName, localObserver, userId);
5541
5542                synchronized(this) {
5543                    // Remove all permissions granted from/to this package
5544                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5545                }
5546
5547                // Remove all zen rules created by this package; revoke it's zen access.
5548                INotificationManager inm = NotificationManager.getService();
5549                inm.removeAutomaticZenRules(packageName);
5550                inm.setNotificationPolicyAccessGranted(packageName, false);
5551
5552            } catch (RemoteException e) {
5553            }
5554        } finally {
5555            Binder.restoreCallingIdentity(callingId);
5556        }
5557        return true;
5558    }
5559
5560    @Override
5561    public void killBackgroundProcesses(final String packageName, int userId) {
5562        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5563                != PackageManager.PERMISSION_GRANTED &&
5564                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5565                        != PackageManager.PERMISSION_GRANTED) {
5566            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5567                    + Binder.getCallingPid()
5568                    + ", uid=" + Binder.getCallingUid()
5569                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5570            Slog.w(TAG, msg);
5571            throw new SecurityException(msg);
5572        }
5573
5574        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5575                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5576        long callingId = Binder.clearCallingIdentity();
5577        try {
5578            IPackageManager pm = AppGlobals.getPackageManager();
5579            synchronized(this) {
5580                int appId = -1;
5581                try {
5582                    appId = UserHandle.getAppId(
5583                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5584                } catch (RemoteException e) {
5585                }
5586                if (appId == -1) {
5587                    Slog.w(TAG, "Invalid packageName: " + packageName);
5588                    return;
5589                }
5590                killPackageProcessesLocked(packageName, appId, userId,
5591                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5592            }
5593        } finally {
5594            Binder.restoreCallingIdentity(callingId);
5595        }
5596    }
5597
5598    @Override
5599    public void killAllBackgroundProcesses() {
5600        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5601                != PackageManager.PERMISSION_GRANTED) {
5602            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5603                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5604                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5605            Slog.w(TAG, msg);
5606            throw new SecurityException(msg);
5607        }
5608
5609        final long callingId = Binder.clearCallingIdentity();
5610        try {
5611            synchronized (this) {
5612                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5613                final int NP = mProcessNames.getMap().size();
5614                for (int ip = 0; ip < NP; ip++) {
5615                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5616                    final int NA = apps.size();
5617                    for (int ia = 0; ia < NA; ia++) {
5618                        final ProcessRecord app = apps.valueAt(ia);
5619                        if (app.persistent) {
5620                            // We don't kill persistent processes.
5621                            continue;
5622                        }
5623                        if (app.removed) {
5624                            procs.add(app);
5625                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5626                            app.removed = true;
5627                            procs.add(app);
5628                        }
5629                    }
5630                }
5631
5632                final int N = procs.size();
5633                for (int i = 0; i < N; i++) {
5634                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5635                }
5636
5637                mAllowLowerMemLevel = true;
5638
5639                updateOomAdjLocked();
5640                doLowMemReportIfNeededLocked(null);
5641            }
5642        } finally {
5643            Binder.restoreCallingIdentity(callingId);
5644        }
5645    }
5646
5647    /**
5648     * Kills all background processes, except those matching any of the
5649     * specified properties.
5650     *
5651     * @param minTargetSdk the target SDK version at or above which to preserve
5652     *                     processes, or {@code -1} to ignore the target SDK
5653     * @param maxProcState the process state at or below which to preserve
5654     *                     processes, or {@code -1} to ignore the process state
5655     */
5656    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5657        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5658                != PackageManager.PERMISSION_GRANTED) {
5659            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5660                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5661                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5662            Slog.w(TAG, msg);
5663            throw new SecurityException(msg);
5664        }
5665
5666        final long callingId = Binder.clearCallingIdentity();
5667        try {
5668            synchronized (this) {
5669                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5670                final int NP = mProcessNames.getMap().size();
5671                for (int ip = 0; ip < NP; ip++) {
5672                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5673                    final int NA = apps.size();
5674                    for (int ia = 0; ia < NA; ia++) {
5675                        final ProcessRecord app = apps.valueAt(ia);
5676                        if (app.removed) {
5677                            procs.add(app);
5678                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5679                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5680                            app.removed = true;
5681                            procs.add(app);
5682                        }
5683                    }
5684                }
5685
5686                final int N = procs.size();
5687                for (int i = 0; i < N; i++) {
5688                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5689                }
5690            }
5691        } finally {
5692            Binder.restoreCallingIdentity(callingId);
5693        }
5694    }
5695
5696    @Override
5697    public void forceStopPackage(final String packageName, int userId) {
5698        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5699                != PackageManager.PERMISSION_GRANTED) {
5700            String msg = "Permission Denial: forceStopPackage() from pid="
5701                    + Binder.getCallingPid()
5702                    + ", uid=" + Binder.getCallingUid()
5703                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5704            Slog.w(TAG, msg);
5705            throw new SecurityException(msg);
5706        }
5707        final int callingPid = Binder.getCallingPid();
5708        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5709                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5710        long callingId = Binder.clearCallingIdentity();
5711        try {
5712            IPackageManager pm = AppGlobals.getPackageManager();
5713            synchronized(this) {
5714                int[] users = userId == UserHandle.USER_ALL
5715                        ? mUserController.getUsers() : new int[] { userId };
5716                for (int user : users) {
5717                    int pkgUid = -1;
5718                    try {
5719                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5720                                user);
5721                    } catch (RemoteException e) {
5722                    }
5723                    if (pkgUid == -1) {
5724                        Slog.w(TAG, "Invalid packageName: " + packageName);
5725                        continue;
5726                    }
5727                    try {
5728                        pm.setPackageStoppedState(packageName, true, user);
5729                    } catch (RemoteException e) {
5730                    } catch (IllegalArgumentException e) {
5731                        Slog.w(TAG, "Failed trying to unstop package "
5732                                + packageName + ": " + e);
5733                    }
5734                    if (mUserController.isUserRunningLocked(user, 0)) {
5735                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5736                        finishForceStopPackageLocked(packageName, pkgUid);
5737                    }
5738                }
5739            }
5740        } finally {
5741            Binder.restoreCallingIdentity(callingId);
5742        }
5743    }
5744
5745    @Override
5746    public void addPackageDependency(String packageName) {
5747        synchronized (this) {
5748            int callingPid = Binder.getCallingPid();
5749            if (callingPid == Process.myPid()) {
5750                //  Yeah, um, no.
5751                return;
5752            }
5753            ProcessRecord proc;
5754            synchronized (mPidsSelfLocked) {
5755                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5756            }
5757            if (proc != null) {
5758                if (proc.pkgDeps == null) {
5759                    proc.pkgDeps = new ArraySet<String>(1);
5760                }
5761                proc.pkgDeps.add(packageName);
5762            }
5763        }
5764    }
5765
5766    /*
5767     * The pkg name and app id have to be specified.
5768     */
5769    @Override
5770    public void killApplication(String pkg, int appId, int userId, String reason) {
5771        if (pkg == null) {
5772            return;
5773        }
5774        // Make sure the uid is valid.
5775        if (appId < 0) {
5776            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5777            return;
5778        }
5779        int callerUid = Binder.getCallingUid();
5780        // Only the system server can kill an application
5781        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5782            // Post an aysnc message to kill the application
5783            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5784            msg.arg1 = appId;
5785            msg.arg2 = userId;
5786            Bundle bundle = new Bundle();
5787            bundle.putString("pkg", pkg);
5788            bundle.putString("reason", reason);
5789            msg.obj = bundle;
5790            mHandler.sendMessage(msg);
5791        } else {
5792            throw new SecurityException(callerUid + " cannot kill pkg: " +
5793                    pkg);
5794        }
5795    }
5796
5797    @Override
5798    public void closeSystemDialogs(String reason) {
5799        enforceNotIsolatedCaller("closeSystemDialogs");
5800
5801        final int pid = Binder.getCallingPid();
5802        final int uid = Binder.getCallingUid();
5803        final long origId = Binder.clearCallingIdentity();
5804        try {
5805            synchronized (this) {
5806                // Only allow this from foreground processes, so that background
5807                // applications can't abuse it to prevent system UI from being shown.
5808                if (uid >= Process.FIRST_APPLICATION_UID) {
5809                    ProcessRecord proc;
5810                    synchronized (mPidsSelfLocked) {
5811                        proc = mPidsSelfLocked.get(pid);
5812                    }
5813                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5814                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5815                                + " from background process " + proc);
5816                        return;
5817                    }
5818                }
5819                closeSystemDialogsLocked(reason);
5820            }
5821        } finally {
5822            Binder.restoreCallingIdentity(origId);
5823        }
5824    }
5825
5826    void closeSystemDialogsLocked(String reason) {
5827        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5828        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5829                | Intent.FLAG_RECEIVER_FOREGROUND);
5830        if (reason != null) {
5831            intent.putExtra("reason", reason);
5832        }
5833        mWindowManager.closeSystemDialogs(reason);
5834
5835        mStackSupervisor.closeSystemDialogsLocked();
5836
5837        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5838                AppOpsManager.OP_NONE, null, false, false,
5839                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5840    }
5841
5842    @Override
5843    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5844        enforceNotIsolatedCaller("getProcessMemoryInfo");
5845        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5846        for (int i=pids.length-1; i>=0; i--) {
5847            ProcessRecord proc;
5848            int oomAdj;
5849            synchronized (this) {
5850                synchronized (mPidsSelfLocked) {
5851                    proc = mPidsSelfLocked.get(pids[i]);
5852                    oomAdj = proc != null ? proc.setAdj : 0;
5853                }
5854            }
5855            infos[i] = new Debug.MemoryInfo();
5856            Debug.getMemoryInfo(pids[i], infos[i]);
5857            if (proc != null) {
5858                synchronized (this) {
5859                    if (proc.thread != null && proc.setAdj == oomAdj) {
5860                        // Record this for posterity if the process has been stable.
5861                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5862                                infos[i].getTotalUss(), false, proc.pkgList);
5863                    }
5864                }
5865            }
5866        }
5867        return infos;
5868    }
5869
5870    @Override
5871    public long[] getProcessPss(int[] pids) {
5872        enforceNotIsolatedCaller("getProcessPss");
5873        long[] pss = new long[pids.length];
5874        for (int i=pids.length-1; i>=0; i--) {
5875            ProcessRecord proc;
5876            int oomAdj;
5877            synchronized (this) {
5878                synchronized (mPidsSelfLocked) {
5879                    proc = mPidsSelfLocked.get(pids[i]);
5880                    oomAdj = proc != null ? proc.setAdj : 0;
5881                }
5882            }
5883            long[] tmpUss = new long[1];
5884            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5885            if (proc != null) {
5886                synchronized (this) {
5887                    if (proc.thread != null && proc.setAdj == oomAdj) {
5888                        // Record this for posterity if the process has been stable.
5889                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5890                    }
5891                }
5892            }
5893        }
5894        return pss;
5895    }
5896
5897    @Override
5898    public void killApplicationProcess(String processName, int uid) {
5899        if (processName == null) {
5900            return;
5901        }
5902
5903        int callerUid = Binder.getCallingUid();
5904        // Only the system server can kill an application
5905        if (callerUid == Process.SYSTEM_UID) {
5906            synchronized (this) {
5907                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5908                if (app != null && app.thread != null) {
5909                    try {
5910                        app.thread.scheduleSuicide();
5911                    } catch (RemoteException e) {
5912                        // If the other end already died, then our work here is done.
5913                    }
5914                } else {
5915                    Slog.w(TAG, "Process/uid not found attempting kill of "
5916                            + processName + " / " + uid);
5917                }
5918            }
5919        } else {
5920            throw new SecurityException(callerUid + " cannot kill app process: " +
5921                    processName);
5922        }
5923    }
5924
5925    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5926        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5927                false, true, false, false, UserHandle.getUserId(uid), reason);
5928    }
5929
5930    private void finishForceStopPackageLocked(final String packageName, int uid) {
5931        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5932                Uri.fromParts("package", packageName, null));
5933        if (!mProcessesReady) {
5934            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5935                    | Intent.FLAG_RECEIVER_FOREGROUND);
5936        }
5937        intent.putExtra(Intent.EXTRA_UID, uid);
5938        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5939        broadcastIntentLocked(null, null, intent,
5940                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5941                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5942    }
5943
5944
5945    private final boolean killPackageProcessesLocked(String packageName, int appId,
5946            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5947            boolean doit, boolean evenPersistent, String reason) {
5948        ArrayList<ProcessRecord> procs = new ArrayList<>();
5949
5950        // Remove all processes this package may have touched: all with the
5951        // same UID (except for the system or root user), and all whose name
5952        // matches the package name.
5953        final int NP = mProcessNames.getMap().size();
5954        for (int ip=0; ip<NP; ip++) {
5955            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5956            final int NA = apps.size();
5957            for (int ia=0; ia<NA; ia++) {
5958                ProcessRecord app = apps.valueAt(ia);
5959                if (app.persistent && !evenPersistent) {
5960                    // we don't kill persistent processes
5961                    continue;
5962                }
5963                if (app.removed) {
5964                    if (doit) {
5965                        procs.add(app);
5966                    }
5967                    continue;
5968                }
5969
5970                // Skip process if it doesn't meet our oom adj requirement.
5971                if (app.setAdj < minOomAdj) {
5972                    continue;
5973                }
5974
5975                // If no package is specified, we call all processes under the
5976                // give user id.
5977                if (packageName == null) {
5978                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5979                        continue;
5980                    }
5981                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5982                        continue;
5983                    }
5984                // Package has been specified, we want to hit all processes
5985                // that match it.  We need to qualify this by the processes
5986                // that are running under the specified app and user ID.
5987                } else {
5988                    final boolean isDep = app.pkgDeps != null
5989                            && app.pkgDeps.contains(packageName);
5990                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5991                        continue;
5992                    }
5993                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5994                        continue;
5995                    }
5996                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5997                        continue;
5998                    }
5999                }
6000
6001                // Process has passed all conditions, kill it!
6002                if (!doit) {
6003                    return true;
6004                }
6005                app.removed = true;
6006                procs.add(app);
6007            }
6008        }
6009
6010        int N = procs.size();
6011        for (int i=0; i<N; i++) {
6012            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6013        }
6014        updateOomAdjLocked();
6015        return N > 0;
6016    }
6017
6018    private void cleanupDisabledPackageComponentsLocked(
6019            String packageName, int userId, boolean killProcess, String[] changedClasses) {
6020
6021        Set<String> disabledClasses = null;
6022        boolean packageDisabled = false;
6023        IPackageManager pm = AppGlobals.getPackageManager();
6024
6025        if (changedClasses == null) {
6026            // Nothing changed...
6027            return;
6028        }
6029
6030        // Determine enable/disable state of the package and its components.
6031        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6032        for (int i = changedClasses.length - 1; i >= 0; i--) {
6033            final String changedClass = changedClasses[i];
6034
6035            if (changedClass.equals(packageName)) {
6036                try {
6037                    // Entire package setting changed
6038                    enabled = pm.getApplicationEnabledSetting(packageName,
6039                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6040                } catch (Exception e) {
6041                    // No such package/component; probably racing with uninstall.  In any
6042                    // event it means we have nothing further to do here.
6043                    return;
6044                }
6045                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6046                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6047                if (packageDisabled) {
6048                    // Entire package is disabled.
6049                    // No need to continue to check component states.
6050                    disabledClasses = null;
6051                    break;
6052                }
6053            } else {
6054                try {
6055                    enabled = pm.getComponentEnabledSetting(
6056                            new ComponentName(packageName, changedClass),
6057                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6058                } catch (Exception e) {
6059                    // As above, probably racing with uninstall.
6060                    return;
6061                }
6062                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6063                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6064                    if (disabledClasses == null) {
6065                        disabledClasses = new ArraySet<>(changedClasses.length);
6066                    }
6067                    disabledClasses.add(changedClass);
6068                }
6069            }
6070        }
6071
6072        if (!packageDisabled && disabledClasses == null) {
6073            // Nothing to do here...
6074            return;
6075        }
6076
6077        // Clean-up disabled activities.
6078        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6079                packageName, disabledClasses, true, false, userId) && mBooted) {
6080            mStackSupervisor.resumeFocusedStackTopActivityLocked();
6081            mStackSupervisor.scheduleIdleLocked();
6082        }
6083
6084        // Clean-up disabled tasks
6085        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6086
6087        // Clean-up disabled services.
6088        mServices.bringDownDisabledPackageServicesLocked(
6089                packageName, disabledClasses, userId, false, killProcess, true);
6090
6091        // Clean-up disabled providers.
6092        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6093        mProviderMap.collectPackageProvidersLocked(
6094                packageName, disabledClasses, true, false, userId, providers);
6095        for (int i = providers.size() - 1; i >= 0; i--) {
6096            removeDyingProviderLocked(null, providers.get(i), true);
6097        }
6098
6099        // Clean-up disabled broadcast receivers.
6100        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6101            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6102                    packageName, disabledClasses, userId, true);
6103        }
6104
6105    }
6106
6107    final boolean clearBroadcastQueueForUserLocked(int userId) {
6108        boolean didSomething = false;
6109        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6110            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6111                    null, null, userId, true);
6112        }
6113        return didSomething;
6114    }
6115
6116    final boolean forceStopPackageLocked(String packageName, int appId,
6117            boolean callerWillRestart, boolean purgeCache, boolean doit,
6118            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6119        int i;
6120
6121        if (userId == UserHandle.USER_ALL && packageName == null) {
6122            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6123        }
6124
6125        if (appId < 0 && packageName != null) {
6126            try {
6127                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6128                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6129            } catch (RemoteException e) {
6130            }
6131        }
6132
6133        if (doit) {
6134            if (packageName != null) {
6135                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6136                        + " user=" + userId + ": " + reason);
6137            } else {
6138                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6139            }
6140
6141            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6142        }
6143
6144        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6145                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6146                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6147
6148        didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName);
6149
6150        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6151                packageName, null, doit, evenPersistent, userId)) {
6152            if (!doit) {
6153                return true;
6154            }
6155            didSomething = true;
6156        }
6157
6158        if (mServices.bringDownDisabledPackageServicesLocked(
6159                packageName, null, userId, evenPersistent, true, doit)) {
6160            if (!doit) {
6161                return true;
6162            }
6163            didSomething = true;
6164        }
6165
6166        if (packageName == null) {
6167            // Remove all sticky broadcasts from this user.
6168            mStickyBroadcasts.remove(userId);
6169        }
6170
6171        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6172        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6173                userId, providers)) {
6174            if (!doit) {
6175                return true;
6176            }
6177            didSomething = true;
6178        }
6179        for (i = providers.size() - 1; i >= 0; i--) {
6180            removeDyingProviderLocked(null, providers.get(i), true);
6181        }
6182
6183        // Remove transient permissions granted from/to this package/user
6184        removeUriPermissionsForPackageLocked(packageName, userId, false);
6185
6186        if (doit) {
6187            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6188                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6189                        packageName, null, userId, doit);
6190            }
6191        }
6192
6193        if (packageName == null || uninstalling) {
6194            // Remove pending intents.  For now we only do this when force
6195            // stopping users, because we have some problems when doing this
6196            // for packages -- app widgets are not currently cleaned up for
6197            // such packages, so they can be left with bad pending intents.
6198            if (mIntentSenderRecords.size() > 0) {
6199                Iterator<WeakReference<PendingIntentRecord>> it
6200                        = mIntentSenderRecords.values().iterator();
6201                while (it.hasNext()) {
6202                    WeakReference<PendingIntentRecord> wpir = it.next();
6203                    if (wpir == null) {
6204                        it.remove();
6205                        continue;
6206                    }
6207                    PendingIntentRecord pir = wpir.get();
6208                    if (pir == null) {
6209                        it.remove();
6210                        continue;
6211                    }
6212                    if (packageName == null) {
6213                        // Stopping user, remove all objects for the user.
6214                        if (pir.key.userId != userId) {
6215                            // Not the same user, skip it.
6216                            continue;
6217                        }
6218                    } else {
6219                        if (UserHandle.getAppId(pir.uid) != appId) {
6220                            // Different app id, skip it.
6221                            continue;
6222                        }
6223                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6224                            // Different user, skip it.
6225                            continue;
6226                        }
6227                        if (!pir.key.packageName.equals(packageName)) {
6228                            // Different package, skip it.
6229                            continue;
6230                        }
6231                    }
6232                    if (!doit) {
6233                        return true;
6234                    }
6235                    didSomething = true;
6236                    it.remove();
6237                    pir.canceled = true;
6238                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6239                        pir.key.activity.pendingResults.remove(pir.ref);
6240                    }
6241                }
6242            }
6243        }
6244
6245        if (doit) {
6246            if (purgeCache && packageName != null) {
6247                AttributeCache ac = AttributeCache.instance();
6248                if (ac != null) {
6249                    ac.removePackage(packageName);
6250                }
6251            }
6252            if (mBooted) {
6253                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6254                mStackSupervisor.scheduleIdleLocked();
6255            }
6256        }
6257
6258        return didSomething;
6259    }
6260
6261    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6262        ProcessRecord old = mProcessNames.remove(name, uid);
6263        if (old != null) {
6264            old.uidRecord.numProcs--;
6265            if (old.uidRecord.numProcs == 0) {
6266                // No more processes using this uid, tell clients it is gone.
6267                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6268                        "No more processes in " + old.uidRecord);
6269                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6270                mActiveUids.remove(uid);
6271                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6272            }
6273            old.uidRecord = null;
6274        }
6275        mIsolatedProcesses.remove(uid);
6276        return old;
6277    }
6278
6279    private final void addProcessNameLocked(ProcessRecord proc) {
6280        // We shouldn't already have a process under this name, but just in case we
6281        // need to clean up whatever may be there now.
6282        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6283        if (old == proc && proc.persistent) {
6284            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6285            Slog.w(TAG, "Re-adding persistent process " + proc);
6286        } else if (old != null) {
6287            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6288        }
6289        UidRecord uidRec = mActiveUids.get(proc.uid);
6290        if (uidRec == null) {
6291            uidRec = new UidRecord(proc.uid);
6292            // This is the first appearance of the uid, report it now!
6293            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6294                    "Creating new process uid: " + uidRec);
6295            mActiveUids.put(proc.uid, uidRec);
6296            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6297            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6298        }
6299        proc.uidRecord = uidRec;
6300
6301        // Reset render thread tid if it was already set, so new process can set it again.
6302        proc.renderThreadTid = 0;
6303        uidRec.numProcs++;
6304        mProcessNames.put(proc.processName, proc.uid, proc);
6305        if (proc.isolated) {
6306            mIsolatedProcesses.put(proc.uid, proc);
6307        }
6308    }
6309
6310    boolean removeProcessLocked(ProcessRecord app,
6311            boolean callerWillRestart, boolean allowRestart, String reason) {
6312        final String name = app.processName;
6313        final int uid = app.uid;
6314        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6315            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6316
6317        ProcessRecord old = mProcessNames.get(name, uid);
6318        if (old != app) {
6319            // This process is no longer active, so nothing to do.
6320            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6321            return false;
6322        }
6323        removeProcessNameLocked(name, uid);
6324        if (mHeavyWeightProcess == app) {
6325            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6326                    mHeavyWeightProcess.userId, 0));
6327            mHeavyWeightProcess = null;
6328        }
6329        boolean needRestart = false;
6330        if (app.pid > 0 && app.pid != MY_PID) {
6331            int pid = app.pid;
6332            synchronized (mPidsSelfLocked) {
6333                mPidsSelfLocked.remove(pid);
6334                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6335            }
6336            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6337            if (app.isolated) {
6338                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6339            }
6340            boolean willRestart = false;
6341            if (app.persistent && !app.isolated) {
6342                if (!callerWillRestart) {
6343                    willRestart = true;
6344                } else {
6345                    needRestart = true;
6346                }
6347            }
6348            app.kill(reason, true);
6349            handleAppDiedLocked(app, willRestart, allowRestart);
6350            if (willRestart) {
6351                removeLruProcessLocked(app);
6352                addAppLocked(app.info, false, null /* ABI override */);
6353            }
6354        } else {
6355            mRemovedProcesses.add(app);
6356        }
6357
6358        return needRestart;
6359    }
6360
6361    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6362        cleanupAppInLaunchingProvidersLocked(app, true);
6363        removeProcessLocked(app, false, true, "timeout publishing content providers");
6364    }
6365
6366    private final void processStartTimedOutLocked(ProcessRecord app) {
6367        final int pid = app.pid;
6368        boolean gone = false;
6369        synchronized (mPidsSelfLocked) {
6370            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6371            if (knownApp != null && knownApp.thread == null) {
6372                mPidsSelfLocked.remove(pid);
6373                gone = true;
6374            }
6375        }
6376
6377        if (gone) {
6378            Slog.w(TAG, "Process " + app + " failed to attach");
6379            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6380                    pid, app.uid, app.processName);
6381            removeProcessNameLocked(app.processName, app.uid);
6382            if (mHeavyWeightProcess == app) {
6383                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6384                        mHeavyWeightProcess.userId, 0));
6385                mHeavyWeightProcess = null;
6386            }
6387            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6388            if (app.isolated) {
6389                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6390            }
6391            // Take care of any launching providers waiting for this process.
6392            cleanupAppInLaunchingProvidersLocked(app, true);
6393            // Take care of any services that are waiting for the process.
6394            mServices.processStartTimedOutLocked(app);
6395            app.kill("start timeout", true);
6396            removeLruProcessLocked(app);
6397            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6398                Slog.w(TAG, "Unattached app died before backup, skipping");
6399                try {
6400                    IBackupManager bm = IBackupManager.Stub.asInterface(
6401                            ServiceManager.getService(Context.BACKUP_SERVICE));
6402                    bm.agentDisconnected(app.info.packageName);
6403                } catch (RemoteException e) {
6404                    // Can't happen; the backup manager is local
6405                }
6406            }
6407            if (isPendingBroadcastProcessLocked(pid)) {
6408                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6409                skipPendingBroadcastLocked(pid);
6410            }
6411        } else {
6412            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6413        }
6414    }
6415
6416    private final boolean attachApplicationLocked(IApplicationThread thread,
6417            int pid) {
6418
6419        // Find the application record that is being attached...  either via
6420        // the pid if we are running in multiple processes, or just pull the
6421        // next app record if we are emulating process with anonymous threads.
6422        ProcessRecord app;
6423        if (pid != MY_PID && pid >= 0) {
6424            synchronized (mPidsSelfLocked) {
6425                app = mPidsSelfLocked.get(pid);
6426            }
6427        } else {
6428            app = null;
6429        }
6430
6431        if (app == null) {
6432            Slog.w(TAG, "No pending application record for pid " + pid
6433                    + " (IApplicationThread " + thread + "); dropping process");
6434            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6435            if (pid > 0 && pid != MY_PID) {
6436                Process.killProcessQuiet(pid);
6437                //TODO: killProcessGroup(app.info.uid, pid);
6438            } else {
6439                try {
6440                    thread.scheduleExit();
6441                } catch (Exception e) {
6442                    // Ignore exceptions.
6443                }
6444            }
6445            return false;
6446        }
6447
6448        // If this application record is still attached to a previous
6449        // process, clean it up now.
6450        if (app.thread != null) {
6451            handleAppDiedLocked(app, true, true);
6452        }
6453
6454        // Tell the process all about itself.
6455
6456        if (DEBUG_ALL) Slog.v(
6457                TAG, "Binding process pid " + pid + " to record " + app);
6458
6459        final String processName = app.processName;
6460        try {
6461            AppDeathRecipient adr = new AppDeathRecipient(
6462                    app, pid, thread);
6463            thread.asBinder().linkToDeath(adr, 0);
6464            app.deathRecipient = adr;
6465        } catch (RemoteException e) {
6466            app.resetPackageList(mProcessStats);
6467            startProcessLocked(app, "link fail", processName);
6468            return false;
6469        }
6470
6471        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6472
6473        app.makeActive(thread, mProcessStats);
6474        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6475        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6476        app.forcingToForeground = null;
6477        updateProcessForegroundLocked(app, false, false);
6478        app.hasShownUi = false;
6479        app.debugging = false;
6480        app.cached = false;
6481        app.killedByAm = false;
6482        app.killed = false;
6483
6484
6485        // We carefully use the same state that PackageManager uses for
6486        // filtering, since we use this flag to decide if we need to install
6487        // providers when user is unlocked later
6488        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6489
6490        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6491
6492        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6493        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6494
6495        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6496            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6497            msg.obj = app;
6498            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6499        }
6500
6501        if (!normalMode) {
6502            Slog.i(TAG, "Launching preboot mode app: " + app);
6503        }
6504
6505        if (DEBUG_ALL) Slog.v(
6506            TAG, "New app record " + app
6507            + " thread=" + thread.asBinder() + " pid=" + pid);
6508        try {
6509            int testMode = IApplicationThread.DEBUG_OFF;
6510            if (mDebugApp != null && mDebugApp.equals(processName)) {
6511                testMode = mWaitForDebugger
6512                    ? IApplicationThread.DEBUG_WAIT
6513                    : IApplicationThread.DEBUG_ON;
6514                app.debugging = true;
6515                if (mDebugTransient) {
6516                    mDebugApp = mOrigDebugApp;
6517                    mWaitForDebugger = mOrigWaitForDebugger;
6518                }
6519            }
6520            String profileFile = app.instrumentationProfileFile;
6521            ParcelFileDescriptor profileFd = null;
6522            int samplingInterval = 0;
6523            boolean profileAutoStop = false;
6524            if (mProfileApp != null && mProfileApp.equals(processName)) {
6525                mProfileProc = app;
6526                profileFile = mProfileFile;
6527                profileFd = mProfileFd;
6528                samplingInterval = mSamplingInterval;
6529                profileAutoStop = mAutoStopProfiler;
6530            }
6531            boolean enableTrackAllocation = false;
6532            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6533                enableTrackAllocation = true;
6534                mTrackAllocationApp = null;
6535            }
6536
6537            // If the app is being launched for restore or full backup, set it up specially
6538            boolean isRestrictedBackupMode = false;
6539            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6540                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6541                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6542                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6543                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6544            }
6545
6546            if (app.instrumentationClass != null) {
6547                notifyPackageUse(app.instrumentationClass.getPackageName(),
6548                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6549            }
6550            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6551                    + processName + " with config " + getGlobalConfiguration());
6552            ApplicationInfo appInfo = app.instrumentationInfo != null
6553                    ? app.instrumentationInfo : app.info;
6554            app.compat = compatibilityInfoForPackageLocked(appInfo);
6555            if (profileFd != null) {
6556                profileFd = profileFd.dup();
6557            }
6558            ProfilerInfo profilerInfo = profileFile == null ? null
6559                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6560
6561            // We deprecated Build.SERIAL and only apps that target pre NMR1
6562            // SDK can see it. Since access to the serial is now behind a
6563            // permission we push down the value.
6564            String buildSerial = Build.UNKNOWN;
6565            if (appInfo.targetSdkVersion <= Build.VERSION_CODES.N_MR1) {
6566                buildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
6567                        ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
6568                        .getSerial();
6569            }
6570
6571            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6572                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6573                    app.instrumentationUiAutomationConnection, testMode,
6574                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6575                    isRestrictedBackupMode || !normalMode, app.persistent,
6576                    new Configuration(getGlobalConfiguration()), app.compat,
6577                    getCommonServicesLocked(app.isolated),
6578                    mCoreSettingsObserver.getCoreSettingsLocked(),
6579                    buildSerial);
6580
6581            updateLruProcessLocked(app, false, null);
6582            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6583        } catch (Exception e) {
6584            // todo: Yikes!  What should we do?  For now we will try to
6585            // start another process, but that could easily get us in
6586            // an infinite loop of restarting processes...
6587            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6588
6589            app.resetPackageList(mProcessStats);
6590            app.unlinkDeathRecipient();
6591            startProcessLocked(app, "bind fail", processName);
6592            return false;
6593        }
6594
6595        // Remove this record from the list of starting applications.
6596        mPersistentStartingProcesses.remove(app);
6597        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6598                "Attach application locked removing on hold: " + app);
6599        mProcessesOnHold.remove(app);
6600
6601        boolean badApp = false;
6602        boolean didSomething = false;
6603
6604        // See if the top visible activity is waiting to run in this process...
6605        if (normalMode) {
6606            try {
6607                if (mStackSupervisor.attachApplicationLocked(app)) {
6608                    didSomething = true;
6609                }
6610            } catch (Exception e) {
6611                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6612                badApp = true;
6613            }
6614        }
6615
6616        // Find any services that should be running in this process...
6617        if (!badApp) {
6618            try {
6619                didSomething |= mServices.attachApplicationLocked(app, processName);
6620            } catch (Exception e) {
6621                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6622                badApp = true;
6623            }
6624        }
6625
6626        // Check if a next-broadcast receiver is in this process...
6627        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6628            try {
6629                didSomething |= sendPendingBroadcastsLocked(app);
6630            } catch (Exception e) {
6631                // If the app died trying to launch the receiver we declare it 'bad'
6632                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6633                badApp = true;
6634            }
6635        }
6636
6637        // Check whether the next backup agent is in this process...
6638        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6639            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6640                    "New app is backup target, launching agent for " + app);
6641            notifyPackageUse(mBackupTarget.appInfo.packageName,
6642                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6643            try {
6644                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6645                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6646                        mBackupTarget.backupMode);
6647            } catch (Exception e) {
6648                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6649                badApp = true;
6650            }
6651        }
6652
6653        if (badApp) {
6654            app.kill("error during init", true);
6655            handleAppDiedLocked(app, false, true);
6656            return false;
6657        }
6658
6659        if (!didSomething) {
6660            updateOomAdjLocked();
6661        }
6662
6663        return true;
6664    }
6665
6666    @Override
6667    public final void attachApplication(IApplicationThread thread) {
6668        synchronized (this) {
6669            int callingPid = Binder.getCallingPid();
6670            final long origId = Binder.clearCallingIdentity();
6671            attachApplicationLocked(thread, callingPid);
6672            Binder.restoreCallingIdentity(origId);
6673        }
6674    }
6675
6676    @Override
6677    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6678        final long origId = Binder.clearCallingIdentity();
6679        synchronized (this) {
6680            ActivityStack stack = ActivityRecord.getStackLocked(token);
6681            if (stack != null) {
6682                ActivityRecord r =
6683                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6684                if (stopProfiling) {
6685                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6686                        try {
6687                            mProfileFd.close();
6688                        } catch (IOException e) {
6689                        }
6690                        clearProfilerLocked();
6691                    }
6692                }
6693            }
6694        }
6695        Binder.restoreCallingIdentity(origId);
6696    }
6697
6698    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6699        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6700                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6701    }
6702
6703    void enableScreenAfterBoot() {
6704        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6705                SystemClock.uptimeMillis());
6706        mWindowManager.enableScreenAfterBoot();
6707
6708        synchronized (this) {
6709            updateEventDispatchingLocked();
6710        }
6711    }
6712
6713    @Override
6714    public void showBootMessage(final CharSequence msg, final boolean always) {
6715        if (Binder.getCallingUid() != Process.myUid()) {
6716            throw new SecurityException();
6717        }
6718        mWindowManager.showBootMessage(msg, always);
6719    }
6720
6721    @Override
6722    public void keyguardWaitingForActivityDrawn() {
6723        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6724        final long token = Binder.clearCallingIdentity();
6725        try {
6726            synchronized (this) {
6727                if (DEBUG_LOCKSCREEN) logLockScreen("");
6728                mWindowManager.keyguardWaitingForActivityDrawn();
6729                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6730                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6731                    updateSleepIfNeededLocked();
6732                }
6733            }
6734        } finally {
6735            Binder.restoreCallingIdentity(token);
6736        }
6737    }
6738
6739    @Override
6740    public void keyguardGoingAway(int flags) {
6741        enforceNotIsolatedCaller("keyguardGoingAway");
6742        final long token = Binder.clearCallingIdentity();
6743        try {
6744            synchronized (this) {
6745                if (DEBUG_LOCKSCREEN) logLockScreen("");
6746                mWindowManager.keyguardGoingAway(flags);
6747                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6748                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6749                    updateSleepIfNeededLocked();
6750
6751                    // Some stack visibility might change (e.g. docked stack)
6752                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6753                    applyVrModeIfNeededLocked(mStackSupervisor.getResumedActivityLocked(), true);
6754                }
6755            }
6756        } finally {
6757            Binder.restoreCallingIdentity(token);
6758        }
6759    }
6760
6761    final void finishBooting() {
6762        synchronized (this) {
6763            if (!mBootAnimationComplete) {
6764                mCallFinishBooting = true;
6765                return;
6766            }
6767            mCallFinishBooting = false;
6768        }
6769
6770        ArraySet<String> completedIsas = new ArraySet<String>();
6771        for (String abi : Build.SUPPORTED_ABIS) {
6772            Process.zygoteProcess.establishZygoteConnectionForAbi(abi);
6773            final String instructionSet = VMRuntime.getInstructionSet(abi);
6774            if (!completedIsas.contains(instructionSet)) {
6775                try {
6776                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6777                } catch (InstallerException e) {
6778                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6779                            e.getMessage() +")");
6780                }
6781                completedIsas.add(instructionSet);
6782            }
6783        }
6784
6785        IntentFilter pkgFilter = new IntentFilter();
6786        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6787        pkgFilter.addDataScheme("package");
6788        mContext.registerReceiver(new BroadcastReceiver() {
6789            @Override
6790            public void onReceive(Context context, Intent intent) {
6791                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6792                if (pkgs != null) {
6793                    for (String pkg : pkgs) {
6794                        synchronized (ActivityManagerService.this) {
6795                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6796                                    0, "query restart")) {
6797                                setResultCode(Activity.RESULT_OK);
6798                                return;
6799                            }
6800                        }
6801                    }
6802                }
6803            }
6804        }, pkgFilter);
6805
6806        IntentFilter dumpheapFilter = new IntentFilter();
6807        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6808        mContext.registerReceiver(new BroadcastReceiver() {
6809            @Override
6810            public void onReceive(Context context, Intent intent) {
6811                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6812                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6813                } else {
6814                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6815                }
6816            }
6817        }, dumpheapFilter);
6818
6819        // Let system services know.
6820        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6821
6822        synchronized (this) {
6823            // Ensure that any processes we had put on hold are now started
6824            // up.
6825            final int NP = mProcessesOnHold.size();
6826            if (NP > 0) {
6827                ArrayList<ProcessRecord> procs =
6828                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6829                for (int ip=0; ip<NP; ip++) {
6830                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6831                            + procs.get(ip));
6832                    startProcessLocked(procs.get(ip), "on-hold", null);
6833                }
6834            }
6835
6836            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6837                // Start looking for apps that are abusing wake locks.
6838                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6839                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6840                // Tell anyone interested that we are done booting!
6841                SystemProperties.set("sys.boot_completed", "1");
6842
6843                // And trigger dev.bootcomplete if we are not showing encryption progress
6844                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6845                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6846                    SystemProperties.set("dev.bootcomplete", "1");
6847                }
6848                mUserController.sendBootCompletedLocked(
6849                        new IIntentReceiver.Stub() {
6850                            @Override
6851                            public void performReceive(Intent intent, int resultCode,
6852                                    String data, Bundle extras, boolean ordered,
6853                                    boolean sticky, int sendingUser) {
6854                                synchronized (ActivityManagerService.this) {
6855                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6856                                            true, false);
6857                                }
6858                            }
6859                        });
6860                scheduleStartProfilesLocked();
6861            }
6862        }
6863    }
6864
6865    @Override
6866    public void bootAnimationComplete() {
6867        final boolean callFinishBooting;
6868        synchronized (this) {
6869            callFinishBooting = mCallFinishBooting;
6870            mBootAnimationComplete = true;
6871        }
6872        if (callFinishBooting) {
6873            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6874            finishBooting();
6875            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6876        }
6877    }
6878
6879    final void ensureBootCompleted() {
6880        boolean booting;
6881        boolean enableScreen;
6882        synchronized (this) {
6883            booting = mBooting;
6884            mBooting = false;
6885            enableScreen = !mBooted;
6886            mBooted = true;
6887        }
6888
6889        if (booting) {
6890            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6891            finishBooting();
6892            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6893        }
6894
6895        if (enableScreen) {
6896            enableScreenAfterBoot();
6897        }
6898    }
6899
6900    @Override
6901    public final void activityResumed(IBinder token) {
6902        final long origId = Binder.clearCallingIdentity();
6903        synchronized(this) {
6904            ActivityStack stack = ActivityRecord.getStackLocked(token);
6905            if (stack != null) {
6906                stack.activityResumedLocked(token);
6907            }
6908        }
6909        Binder.restoreCallingIdentity(origId);
6910    }
6911
6912    @Override
6913    public final void activityPaused(IBinder token) {
6914        final long origId = Binder.clearCallingIdentity();
6915        synchronized(this) {
6916            ActivityStack stack = ActivityRecord.getStackLocked(token);
6917            if (stack != null) {
6918                stack.activityPausedLocked(token, false);
6919            }
6920        }
6921        Binder.restoreCallingIdentity(origId);
6922    }
6923
6924    @Override
6925    public final void activityStopped(IBinder token, Bundle icicle,
6926            PersistableBundle persistentState, CharSequence description) {
6927        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6928
6929        // Refuse possible leaked file descriptors
6930        if (icicle != null && icicle.hasFileDescriptors()) {
6931            throw new IllegalArgumentException("File descriptors passed in Bundle");
6932        }
6933
6934        final long origId = Binder.clearCallingIdentity();
6935
6936        synchronized (this) {
6937            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
6938            if (r != null) {
6939                r.getStack().activityStoppedLocked(r, icicle, persistentState, description);
6940            }
6941        }
6942
6943        trimApplications();
6944
6945        Binder.restoreCallingIdentity(origId);
6946    }
6947
6948    @Override
6949    public final void activityDestroyed(IBinder token) {
6950        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6951        synchronized (this) {
6952            ActivityStack stack = ActivityRecord.getStackLocked(token);
6953            if (stack != null) {
6954                stack.activityDestroyedLocked(token, "activityDestroyed");
6955            }
6956        }
6957    }
6958
6959    @Override
6960    public final void activityRelaunched(IBinder token) {
6961        final long origId = Binder.clearCallingIdentity();
6962        synchronized (this) {
6963            mStackSupervisor.activityRelaunchedLocked(token);
6964        }
6965        Binder.restoreCallingIdentity(origId);
6966    }
6967
6968    @Override
6969    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6970            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6971        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6972                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6973        synchronized (this) {
6974            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6975            if (record == null) {
6976                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6977                        + "found for: " + token);
6978            }
6979            record.setSizeConfigurations(horizontalSizeConfiguration,
6980                    verticalSizeConfigurations, smallestSizeConfigurations);
6981        }
6982    }
6983
6984    @Override
6985    public final void backgroundResourcesReleased(IBinder token) {
6986        final long origId = Binder.clearCallingIdentity();
6987        try {
6988            synchronized (this) {
6989                ActivityStack stack = ActivityRecord.getStackLocked(token);
6990                if (stack != null) {
6991                    stack.backgroundResourcesReleased();
6992                }
6993            }
6994        } finally {
6995            Binder.restoreCallingIdentity(origId);
6996        }
6997    }
6998
6999    @Override
7000    public final void notifyLaunchTaskBehindComplete(IBinder token) {
7001        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7002    }
7003
7004    @Override
7005    public final void notifyEnterAnimationComplete(IBinder token) {
7006        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7007    }
7008
7009    @Override
7010    public String getCallingPackage(IBinder token) {
7011        synchronized (this) {
7012            ActivityRecord r = getCallingRecordLocked(token);
7013            return r != null ? r.info.packageName : null;
7014        }
7015    }
7016
7017    @Override
7018    public ComponentName getCallingActivity(IBinder token) {
7019        synchronized (this) {
7020            ActivityRecord r = getCallingRecordLocked(token);
7021            return r != null ? r.intent.getComponent() : null;
7022        }
7023    }
7024
7025    private ActivityRecord getCallingRecordLocked(IBinder token) {
7026        ActivityRecord r = ActivityRecord.isInStackLocked(token);
7027        if (r == null) {
7028            return null;
7029        }
7030        return r.resultTo;
7031    }
7032
7033    @Override
7034    public ComponentName getActivityClassForToken(IBinder token) {
7035        synchronized(this) {
7036            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7037            if (r == null) {
7038                return null;
7039            }
7040            return r.intent.getComponent();
7041        }
7042    }
7043
7044    @Override
7045    public String getPackageForToken(IBinder token) {
7046        synchronized(this) {
7047            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7048            if (r == null) {
7049                return null;
7050            }
7051            return r.packageName;
7052        }
7053    }
7054
7055    @Override
7056    public boolean isRootVoiceInteraction(IBinder token) {
7057        synchronized(this) {
7058            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7059            if (r == null) {
7060                return false;
7061            }
7062            return r.rootVoiceInteraction;
7063        }
7064    }
7065
7066    @Override
7067    public IIntentSender getIntentSender(int type,
7068            String packageName, IBinder token, String resultWho,
7069            int requestCode, Intent[] intents, String[] resolvedTypes,
7070            int flags, Bundle bOptions, int userId) {
7071        enforceNotIsolatedCaller("getIntentSender");
7072        // Refuse possible leaked file descriptors
7073        if (intents != null) {
7074            if (intents.length < 1) {
7075                throw new IllegalArgumentException("Intents array length must be >= 1");
7076            }
7077            for (int i=0; i<intents.length; i++) {
7078                Intent intent = intents[i];
7079                if (intent != null) {
7080                    if (intent.hasFileDescriptors()) {
7081                        throw new IllegalArgumentException("File descriptors passed in Intent");
7082                    }
7083                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7084                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7085                        throw new IllegalArgumentException(
7086                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7087                    }
7088                    intents[i] = new Intent(intent);
7089                }
7090            }
7091            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7092                throw new IllegalArgumentException(
7093                        "Intent array length does not match resolvedTypes length");
7094            }
7095        }
7096        if (bOptions != null) {
7097            if (bOptions.hasFileDescriptors()) {
7098                throw new IllegalArgumentException("File descriptors passed in options");
7099            }
7100        }
7101
7102        synchronized(this) {
7103            int callingUid = Binder.getCallingUid();
7104            int origUserId = userId;
7105            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7106                    type == ActivityManager.INTENT_SENDER_BROADCAST,
7107                    ALLOW_NON_FULL, "getIntentSender", null);
7108            if (origUserId == UserHandle.USER_CURRENT) {
7109                // We don't want to evaluate this until the pending intent is
7110                // actually executed.  However, we do want to always do the
7111                // security checking for it above.
7112                userId = UserHandle.USER_CURRENT;
7113            }
7114            try {
7115                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7116                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7117                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7118                    if (!UserHandle.isSameApp(callingUid, uid)) {
7119                        String msg = "Permission Denial: getIntentSender() from pid="
7120                            + Binder.getCallingPid()
7121                            + ", uid=" + Binder.getCallingUid()
7122                            + ", (need uid=" + uid + ")"
7123                            + " is not allowed to send as package " + packageName;
7124                        Slog.w(TAG, msg);
7125                        throw new SecurityException(msg);
7126                    }
7127                }
7128
7129                return getIntentSenderLocked(type, packageName, callingUid, userId,
7130                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7131
7132            } catch (RemoteException e) {
7133                throw new SecurityException(e);
7134            }
7135        }
7136    }
7137
7138    IIntentSender getIntentSenderLocked(int type, String packageName,
7139            int callingUid, int userId, IBinder token, String resultWho,
7140            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7141            Bundle bOptions) {
7142        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7143        ActivityRecord activity = null;
7144        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7145            activity = ActivityRecord.isInStackLocked(token);
7146            if (activity == null) {
7147                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7148                return null;
7149            }
7150            if (activity.finishing) {
7151                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7152                return null;
7153            }
7154        }
7155
7156        // We're going to be splicing together extras before sending, so we're
7157        // okay poking into any contained extras.
7158        if (intents != null) {
7159            for (int i = 0; i < intents.length; i++) {
7160                intents[i].setDefusable(true);
7161            }
7162        }
7163        Bundle.setDefusable(bOptions, true);
7164
7165        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7166        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7167        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7168        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7169                |PendingIntent.FLAG_UPDATE_CURRENT);
7170
7171        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7172                type, packageName, activity, resultWho,
7173                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7174        WeakReference<PendingIntentRecord> ref;
7175        ref = mIntentSenderRecords.get(key);
7176        PendingIntentRecord rec = ref != null ? ref.get() : null;
7177        if (rec != null) {
7178            if (!cancelCurrent) {
7179                if (updateCurrent) {
7180                    if (rec.key.requestIntent != null) {
7181                        rec.key.requestIntent.replaceExtras(intents != null ?
7182                                intents[intents.length - 1] : null);
7183                    }
7184                    if (intents != null) {
7185                        intents[intents.length-1] = rec.key.requestIntent;
7186                        rec.key.allIntents = intents;
7187                        rec.key.allResolvedTypes = resolvedTypes;
7188                    } else {
7189                        rec.key.allIntents = null;
7190                        rec.key.allResolvedTypes = null;
7191                    }
7192                }
7193                return rec;
7194            }
7195            rec.canceled = true;
7196            mIntentSenderRecords.remove(key);
7197        }
7198        if (noCreate) {
7199            return rec;
7200        }
7201        rec = new PendingIntentRecord(this, key, callingUid);
7202        mIntentSenderRecords.put(key, rec.ref);
7203        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7204            if (activity.pendingResults == null) {
7205                activity.pendingResults
7206                        = new HashSet<WeakReference<PendingIntentRecord>>();
7207            }
7208            activity.pendingResults.add(rec.ref);
7209        }
7210        return rec;
7211    }
7212
7213    @Override
7214    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7215            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7216        if (target instanceof PendingIntentRecord) {
7217            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7218                    finishedReceiver, requiredPermission, options);
7219        } else {
7220            if (intent == null) {
7221                // Weird case: someone has given us their own custom IIntentSender, and now
7222                // they have someone else trying to send to it but of course this isn't
7223                // really a PendingIntent, so there is no base Intent, and the caller isn't
7224                // supplying an Intent... but we never want to dispatch a null Intent to
7225                // a receiver, so um...  let's make something up.
7226                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7227                intent = new Intent(Intent.ACTION_MAIN);
7228            }
7229            try {
7230                target.send(code, intent, resolvedType, null, requiredPermission, options);
7231            } catch (RemoteException e) {
7232            }
7233            // Platform code can rely on getting a result back when the send is done, but if
7234            // this intent sender is from outside of the system we can't rely on it doing that.
7235            // So instead we don't give it the result receiver, and instead just directly
7236            // report the finish immediately.
7237            if (finishedReceiver != null) {
7238                try {
7239                    finishedReceiver.performReceive(intent, 0,
7240                            null, null, false, false, UserHandle.getCallingUserId());
7241                } catch (RemoteException e) {
7242                }
7243            }
7244            return 0;
7245        }
7246    }
7247
7248    /**
7249     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7250     *
7251     * <p>{@code callerUid} must be allowed to request such whitelist by calling
7252     * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7253     */
7254    void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7255        if (DEBUG_WHITELISTS) {
7256            Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7257                    + targetUid + ", " + duration + ")");
7258        }
7259        synchronized (mPidsSelfLocked) {
7260            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7261            if (pr == null) {
7262                Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7263                return;
7264            }
7265            if (!pr.whitelistManager) {
7266                if (DEBUG_WHITELISTS) {
7267                    Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7268                            + callerPid + " is not allowed");
7269                }
7270                return;
7271            }
7272        }
7273
7274        final long token = Binder.clearCallingIdentity();
7275        try {
7276            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7277                    true, "pe from uid:" + callerUid);
7278        } finally {
7279            Binder.restoreCallingIdentity(token);
7280        }
7281    }
7282
7283    @Override
7284    public void cancelIntentSender(IIntentSender sender) {
7285        if (!(sender instanceof PendingIntentRecord)) {
7286            return;
7287        }
7288        synchronized(this) {
7289            PendingIntentRecord rec = (PendingIntentRecord)sender;
7290            try {
7291                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7292                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7293                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7294                    String msg = "Permission Denial: cancelIntentSender() from pid="
7295                        + Binder.getCallingPid()
7296                        + ", uid=" + Binder.getCallingUid()
7297                        + " is not allowed to cancel packges "
7298                        + rec.key.packageName;
7299                    Slog.w(TAG, msg);
7300                    throw new SecurityException(msg);
7301                }
7302            } catch (RemoteException e) {
7303                throw new SecurityException(e);
7304            }
7305            cancelIntentSenderLocked(rec, true);
7306        }
7307    }
7308
7309    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7310        rec.canceled = true;
7311        mIntentSenderRecords.remove(rec.key);
7312        if (cleanActivity && rec.key.activity != null) {
7313            rec.key.activity.pendingResults.remove(rec.ref);
7314        }
7315    }
7316
7317    @Override
7318    public String getPackageForIntentSender(IIntentSender pendingResult) {
7319        if (!(pendingResult instanceof PendingIntentRecord)) {
7320            return null;
7321        }
7322        try {
7323            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7324            return res.key.packageName;
7325        } catch (ClassCastException e) {
7326        }
7327        return null;
7328    }
7329
7330    @Override
7331    public int getUidForIntentSender(IIntentSender sender) {
7332        if (sender instanceof PendingIntentRecord) {
7333            try {
7334                PendingIntentRecord res = (PendingIntentRecord)sender;
7335                return res.uid;
7336            } catch (ClassCastException e) {
7337            }
7338        }
7339        return -1;
7340    }
7341
7342    @Override
7343    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7344        if (!(pendingResult instanceof PendingIntentRecord)) {
7345            return false;
7346        }
7347        try {
7348            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7349            if (res.key.allIntents == null) {
7350                return false;
7351            }
7352            for (int i=0; i<res.key.allIntents.length; i++) {
7353                Intent intent = res.key.allIntents[i];
7354                if (intent.getPackage() != null && intent.getComponent() != null) {
7355                    return false;
7356                }
7357            }
7358            return true;
7359        } catch (ClassCastException e) {
7360        }
7361        return false;
7362    }
7363
7364    @Override
7365    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7366        if (!(pendingResult instanceof PendingIntentRecord)) {
7367            return false;
7368        }
7369        try {
7370            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7371            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7372                return true;
7373            }
7374            return false;
7375        } catch (ClassCastException e) {
7376        }
7377        return false;
7378    }
7379
7380    @Override
7381    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7382        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7383                "getIntentForIntentSender()");
7384        if (!(pendingResult instanceof PendingIntentRecord)) {
7385            return null;
7386        }
7387        try {
7388            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7389            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7390        } catch (ClassCastException e) {
7391        }
7392        return null;
7393    }
7394
7395    @Override
7396    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7397        if (!(pendingResult instanceof PendingIntentRecord)) {
7398            return null;
7399        }
7400        try {
7401            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7402            synchronized (this) {
7403                return getTagForIntentSenderLocked(res, prefix);
7404            }
7405        } catch (ClassCastException e) {
7406        }
7407        return null;
7408    }
7409
7410    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7411        final Intent intent = res.key.requestIntent;
7412        if (intent != null) {
7413            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7414                    || res.lastTagPrefix.equals(prefix))) {
7415                return res.lastTag;
7416            }
7417            res.lastTagPrefix = prefix;
7418            final StringBuilder sb = new StringBuilder(128);
7419            if (prefix != null) {
7420                sb.append(prefix);
7421            }
7422            if (intent.getAction() != null) {
7423                sb.append(intent.getAction());
7424            } else if (intent.getComponent() != null) {
7425                intent.getComponent().appendShortString(sb);
7426            } else {
7427                sb.append("?");
7428            }
7429            return res.lastTag = sb.toString();
7430        }
7431        return null;
7432    }
7433
7434    @Override
7435    public void setProcessLimit(int max) {
7436        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7437                "setProcessLimit()");
7438        synchronized (this) {
7439            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7440            mProcessLimitOverride = max;
7441        }
7442        trimApplications();
7443    }
7444
7445    @Override
7446    public int getProcessLimit() {
7447        synchronized (this) {
7448            return mProcessLimitOverride;
7449        }
7450    }
7451
7452    void foregroundTokenDied(ForegroundToken token) {
7453        synchronized (ActivityManagerService.this) {
7454            synchronized (mPidsSelfLocked) {
7455                ForegroundToken cur
7456                    = mForegroundProcesses.get(token.pid);
7457                if (cur != token) {
7458                    return;
7459                }
7460                mForegroundProcesses.remove(token.pid);
7461                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7462                if (pr == null) {
7463                    return;
7464                }
7465                pr.forcingToForeground = null;
7466                updateProcessForegroundLocked(pr, false, false);
7467            }
7468            updateOomAdjLocked();
7469        }
7470    }
7471
7472    @Override
7473    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7474        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7475                "setProcessForeground()");
7476        synchronized(this) {
7477            boolean changed = false;
7478
7479            synchronized (mPidsSelfLocked) {
7480                ProcessRecord pr = mPidsSelfLocked.get(pid);
7481                if (pr == null && isForeground) {
7482                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7483                    return;
7484                }
7485                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7486                if (oldToken != null) {
7487                    oldToken.token.unlinkToDeath(oldToken, 0);
7488                    mForegroundProcesses.remove(pid);
7489                    if (pr != null) {
7490                        pr.forcingToForeground = null;
7491                    }
7492                    changed = true;
7493                }
7494                if (isForeground && token != null) {
7495                    ForegroundToken newToken = new ForegroundToken() {
7496                        @Override
7497                        public void binderDied() {
7498                            foregroundTokenDied(this);
7499                        }
7500                    };
7501                    newToken.pid = pid;
7502                    newToken.token = token;
7503                    try {
7504                        token.linkToDeath(newToken, 0);
7505                        mForegroundProcesses.put(pid, newToken);
7506                        pr.forcingToForeground = token;
7507                        changed = true;
7508                    } catch (RemoteException e) {
7509                        // If the process died while doing this, we will later
7510                        // do the cleanup with the process death link.
7511                    }
7512                }
7513            }
7514
7515            if (changed) {
7516                updateOomAdjLocked();
7517            }
7518        }
7519    }
7520
7521    @Override
7522    public boolean isAppForeground(int uid) throws RemoteException {
7523        synchronized (this) {
7524            UidRecord uidRec = mActiveUids.get(uid);
7525            if (uidRec == null || uidRec.idle) {
7526                return false;
7527            }
7528            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7529        }
7530    }
7531
7532    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7533    // be guarded by permission checking.
7534    int getUidState(int uid) {
7535        synchronized (this) {
7536            UidRecord uidRec = mActiveUids.get(uid);
7537            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7538        }
7539    }
7540
7541    @Override
7542    public boolean isInMultiWindowMode(IBinder token) {
7543        final long origId = Binder.clearCallingIdentity();
7544        try {
7545            synchronized(this) {
7546                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7547                if (r == null) {
7548                    return false;
7549                }
7550                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7551                return !r.task.mFullscreen;
7552            }
7553        } finally {
7554            Binder.restoreCallingIdentity(origId);
7555        }
7556    }
7557
7558    @Override
7559    public boolean isInPictureInPictureMode(IBinder token) {
7560        final long origId = Binder.clearCallingIdentity();
7561        try {
7562            synchronized(this) {
7563                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7564                if (stack == null) {
7565                    return false;
7566                }
7567                return stack.mStackId == PINNED_STACK_ID;
7568            }
7569        } finally {
7570            Binder.restoreCallingIdentity(origId);
7571        }
7572    }
7573
7574    @Override
7575    public void enterPictureInPictureMode(IBinder token) {
7576        final long origId = Binder.clearCallingIdentity();
7577        try {
7578            synchronized(this) {
7579                if (!mSupportsPictureInPicture) {
7580                    throw new IllegalStateException("enterPictureInPictureMode: "
7581                            + "Device doesn't support picture-in-picture mode.");
7582                }
7583
7584                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7585
7586                if (r == null) {
7587                    throw new IllegalStateException("enterPictureInPictureMode: "
7588                            + "Can't find activity for token=" + token);
7589                }
7590
7591                if (!r.supportsPictureInPicture()) {
7592                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7593                            + "Picture-In-Picture not supported for r=" + r);
7594                }
7595
7596                // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7597                // current bounds.
7598                final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7599                final Rect bounds = (pinnedStack != null)
7600                        ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7601
7602                mStackSupervisor.moveActivityToPinnedStackLocked(
7603                        r, "enterPictureInPictureMode", bounds);
7604            }
7605        } finally {
7606            Binder.restoreCallingIdentity(origId);
7607        }
7608    }
7609
7610    // =========================================================
7611    // PROCESS INFO
7612    // =========================================================
7613
7614    static class ProcessInfoService extends IProcessInfoService.Stub {
7615        final ActivityManagerService mActivityManagerService;
7616        ProcessInfoService(ActivityManagerService activityManagerService) {
7617            mActivityManagerService = activityManagerService;
7618        }
7619
7620        @Override
7621        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7622            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7623                    /*in*/ pids, /*out*/ states, null);
7624        }
7625
7626        @Override
7627        public void getProcessStatesAndOomScoresFromPids(
7628                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7629            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7630                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7631        }
7632    }
7633
7634    /**
7635     * For each PID in the given input array, write the current process state
7636     * for that process into the states array, or -1 to indicate that no
7637     * process with the given PID exists. If scores array is provided, write
7638     * the oom score for the process into the scores array, with INVALID_ADJ
7639     * indicating the PID doesn't exist.
7640     */
7641    public void getProcessStatesAndOomScoresForPIDs(
7642            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7643        if (scores != null) {
7644            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7645                    "getProcessStatesAndOomScoresForPIDs()");
7646        }
7647
7648        if (pids == null) {
7649            throw new NullPointerException("pids");
7650        } else if (states == null) {
7651            throw new NullPointerException("states");
7652        } else if (pids.length != states.length) {
7653            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7654        } else if (scores != null && pids.length != scores.length) {
7655            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7656        }
7657
7658        synchronized (mPidsSelfLocked) {
7659            for (int i = 0; i < pids.length; i++) {
7660                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7661                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7662                        pr.curProcState;
7663                if (scores != null) {
7664                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7665                }
7666            }
7667        }
7668    }
7669
7670    // =========================================================
7671    // PERMISSIONS
7672    // =========================================================
7673
7674    static class PermissionController extends IPermissionController.Stub {
7675        ActivityManagerService mActivityManagerService;
7676        PermissionController(ActivityManagerService activityManagerService) {
7677            mActivityManagerService = activityManagerService;
7678        }
7679
7680        @Override
7681        public boolean checkPermission(String permission, int pid, int uid) {
7682            return mActivityManagerService.checkPermission(permission, pid,
7683                    uid) == PackageManager.PERMISSION_GRANTED;
7684        }
7685
7686        @Override
7687        public String[] getPackagesForUid(int uid) {
7688            return mActivityManagerService.mContext.getPackageManager()
7689                    .getPackagesForUid(uid);
7690        }
7691
7692        @Override
7693        public boolean isRuntimePermission(String permission) {
7694            try {
7695                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7696                        .getPermissionInfo(permission, 0);
7697                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7698            } catch (NameNotFoundException nnfe) {
7699                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7700            }
7701            return false;
7702        }
7703    }
7704
7705    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7706        @Override
7707        public int checkComponentPermission(String permission, int pid, int uid,
7708                int owningUid, boolean exported) {
7709            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7710                    owningUid, exported);
7711        }
7712
7713        @Override
7714        public Object getAMSLock() {
7715            return ActivityManagerService.this;
7716        }
7717    }
7718
7719    /**
7720     * This can be called with or without the global lock held.
7721     */
7722    int checkComponentPermission(String permission, int pid, int uid,
7723            int owningUid, boolean exported) {
7724        if (pid == MY_PID) {
7725            return PackageManager.PERMISSION_GRANTED;
7726        }
7727        return ActivityManager.checkComponentPermission(permission, uid,
7728                owningUid, exported);
7729    }
7730
7731    /**
7732     * As the only public entry point for permissions checking, this method
7733     * can enforce the semantic that requesting a check on a null global
7734     * permission is automatically denied.  (Internally a null permission
7735     * string is used when calling {@link #checkComponentPermission} in cases
7736     * when only uid-based security is needed.)
7737     *
7738     * This can be called with or without the global lock held.
7739     */
7740    @Override
7741    public int checkPermission(String permission, int pid, int uid) {
7742        if (permission == null) {
7743            return PackageManager.PERMISSION_DENIED;
7744        }
7745        return checkComponentPermission(permission, pid, uid, -1, true);
7746    }
7747
7748    @Override
7749    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7750        if (permission == null) {
7751            return PackageManager.PERMISSION_DENIED;
7752        }
7753
7754        // We might be performing an operation on behalf of an indirect binder
7755        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7756        // client identity accordingly before proceeding.
7757        Identity tlsIdentity = sCallerIdentity.get();
7758        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7759            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7760                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7761            uid = tlsIdentity.uid;
7762            pid = tlsIdentity.pid;
7763        }
7764
7765        return checkComponentPermission(permission, pid, uid, -1, true);
7766    }
7767
7768    /**
7769     * Binder IPC calls go through the public entry point.
7770     * This can be called with or without the global lock held.
7771     */
7772    int checkCallingPermission(String permission) {
7773        return checkPermission(permission,
7774                Binder.getCallingPid(),
7775                UserHandle.getAppId(Binder.getCallingUid()));
7776    }
7777
7778    /**
7779     * This can be called with or without the global lock held.
7780     */
7781    void enforceCallingPermission(String permission, String func) {
7782        if (checkCallingPermission(permission)
7783                == PackageManager.PERMISSION_GRANTED) {
7784            return;
7785        }
7786
7787        String msg = "Permission Denial: " + func + " from pid="
7788                + Binder.getCallingPid()
7789                + ", uid=" + Binder.getCallingUid()
7790                + " requires " + permission;
7791        Slog.w(TAG, msg);
7792        throw new SecurityException(msg);
7793    }
7794
7795    /**
7796     * Determine if UID is holding permissions required to access {@link Uri} in
7797     * the given {@link ProviderInfo}. Final permission checking is always done
7798     * in {@link ContentProvider}.
7799     */
7800    private final boolean checkHoldingPermissionsLocked(
7801            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7802        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7803                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7804        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7805            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7806                    != PERMISSION_GRANTED) {
7807                return false;
7808            }
7809        }
7810        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7811    }
7812
7813    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7814            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7815        if (pi.applicationInfo.uid == uid) {
7816            return true;
7817        } else if (!pi.exported) {
7818            return false;
7819        }
7820
7821        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7822        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7823        try {
7824            // check if target holds top-level <provider> permissions
7825            if (!readMet && pi.readPermission != null && considerUidPermissions
7826                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7827                readMet = true;
7828            }
7829            if (!writeMet && pi.writePermission != null && considerUidPermissions
7830                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7831                writeMet = true;
7832            }
7833
7834            // track if unprotected read/write is allowed; any denied
7835            // <path-permission> below removes this ability
7836            boolean allowDefaultRead = pi.readPermission == null;
7837            boolean allowDefaultWrite = pi.writePermission == null;
7838
7839            // check if target holds any <path-permission> that match uri
7840            final PathPermission[] pps = pi.pathPermissions;
7841            if (pps != null) {
7842                final String path = grantUri.uri.getPath();
7843                int i = pps.length;
7844                while (i > 0 && (!readMet || !writeMet)) {
7845                    i--;
7846                    PathPermission pp = pps[i];
7847                    if (pp.match(path)) {
7848                        if (!readMet) {
7849                            final String pprperm = pp.getReadPermission();
7850                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7851                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7852                                    + ": match=" + pp.match(path)
7853                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7854                            if (pprperm != null) {
7855                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7856                                        == PERMISSION_GRANTED) {
7857                                    readMet = true;
7858                                } else {
7859                                    allowDefaultRead = false;
7860                                }
7861                            }
7862                        }
7863                        if (!writeMet) {
7864                            final String ppwperm = pp.getWritePermission();
7865                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7866                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7867                                    + ": match=" + pp.match(path)
7868                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7869                            if (ppwperm != null) {
7870                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7871                                        == PERMISSION_GRANTED) {
7872                                    writeMet = true;
7873                                } else {
7874                                    allowDefaultWrite = false;
7875                                }
7876                            }
7877                        }
7878                    }
7879                }
7880            }
7881
7882            // grant unprotected <provider> read/write, if not blocked by
7883            // <path-permission> above
7884            if (allowDefaultRead) readMet = true;
7885            if (allowDefaultWrite) writeMet = true;
7886
7887        } catch (RemoteException e) {
7888            return false;
7889        }
7890
7891        return readMet && writeMet;
7892    }
7893
7894    public int getAppStartMode(int uid, String packageName) {
7895        synchronized (this) {
7896            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7897        }
7898    }
7899
7900    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7901            boolean allowWhenForeground) {
7902        UidRecord uidRec = mActiveUids.get(uid);
7903        if (!mLenientBackgroundCheck) {
7904            if (!allowWhenForeground || uidRec == null
7905                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7906                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7907                        packageName) != AppOpsManager.MODE_ALLOWED) {
7908                    return ActivityManager.APP_START_MODE_DELAYED;
7909                }
7910            }
7911
7912        } else if (uidRec == null || uidRec.idle) {
7913            if (callingPid >= 0) {
7914                ProcessRecord proc;
7915                synchronized (mPidsSelfLocked) {
7916                    proc = mPidsSelfLocked.get(callingPid);
7917                }
7918                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7919                    // Whoever is instigating this is in the foreground, so we will allow it
7920                    // to go through.
7921                    return ActivityManager.APP_START_MODE_NORMAL;
7922                }
7923            }
7924            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7925                    != AppOpsManager.MODE_ALLOWED) {
7926                return ActivityManager.APP_START_MODE_DELAYED;
7927            }
7928        }
7929        return ActivityManager.APP_START_MODE_NORMAL;
7930    }
7931
7932    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
7933        ProviderInfo pi = null;
7934        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7935        if (cpr != null) {
7936            pi = cpr.info;
7937        } else {
7938            try {
7939                pi = AppGlobals.getPackageManager().resolveContentProvider(
7940                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
7941                        userHandle);
7942            } catch (RemoteException ex) {
7943            }
7944        }
7945        return pi;
7946    }
7947
7948    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7949        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7950        if (targetUris != null) {
7951            return targetUris.get(grantUri);
7952        }
7953        return null;
7954    }
7955
7956    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7957            String targetPkg, int targetUid, GrantUri grantUri) {
7958        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7959        if (targetUris == null) {
7960            targetUris = Maps.newArrayMap();
7961            mGrantedUriPermissions.put(targetUid, targetUris);
7962        }
7963
7964        UriPermission perm = targetUris.get(grantUri);
7965        if (perm == null) {
7966            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7967            targetUris.put(grantUri, perm);
7968        }
7969
7970        return perm;
7971    }
7972
7973    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7974            final int modeFlags) {
7975        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7976        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7977                : UriPermission.STRENGTH_OWNED;
7978
7979        // Root gets to do everything.
7980        if (uid == 0) {
7981            return true;
7982        }
7983
7984        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7985        if (perms == null) return false;
7986
7987        // First look for exact match
7988        final UriPermission exactPerm = perms.get(grantUri);
7989        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7990            return true;
7991        }
7992
7993        // No exact match, look for prefixes
7994        final int N = perms.size();
7995        for (int i = 0; i < N; i++) {
7996            final UriPermission perm = perms.valueAt(i);
7997            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7998                    && perm.getStrength(modeFlags) >= minStrength) {
7999                return true;
8000            }
8001        }
8002
8003        return false;
8004    }
8005
8006    /**
8007     * @param uri This uri must NOT contain an embedded userId.
8008     * @param userId The userId in which the uri is to be resolved.
8009     */
8010    @Override
8011    public int checkUriPermission(Uri uri, int pid, int uid,
8012            final int modeFlags, int userId, IBinder callerToken) {
8013        enforceNotIsolatedCaller("checkUriPermission");
8014
8015        // Another redirected-binder-call permissions check as in
8016        // {@link checkPermissionWithToken}.
8017        Identity tlsIdentity = sCallerIdentity.get();
8018        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8019            uid = tlsIdentity.uid;
8020            pid = tlsIdentity.pid;
8021        }
8022
8023        // Our own process gets to do everything.
8024        if (pid == MY_PID) {
8025            return PackageManager.PERMISSION_GRANTED;
8026        }
8027        synchronized (this) {
8028            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8029                    ? PackageManager.PERMISSION_GRANTED
8030                    : PackageManager.PERMISSION_DENIED;
8031        }
8032    }
8033
8034    /**
8035     * Check if the targetPkg can be granted permission to access uri by
8036     * the callingUid using the given modeFlags.  Throws a security exception
8037     * if callingUid is not allowed to do this.  Returns the uid of the target
8038     * if the URI permission grant should be performed; returns -1 if it is not
8039     * needed (for example targetPkg already has permission to access the URI).
8040     * If you already know the uid of the target, you can supply it in
8041     * lastTargetUid else set that to -1.
8042     */
8043    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8044            final int modeFlags, int lastTargetUid) {
8045        if (!Intent.isAccessUriMode(modeFlags)) {
8046            return -1;
8047        }
8048
8049        if (targetPkg != null) {
8050            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8051                    "Checking grant " + targetPkg + " permission to " + grantUri);
8052        }
8053
8054        final IPackageManager pm = AppGlobals.getPackageManager();
8055
8056        // If this is not a content: uri, we can't do anything with it.
8057        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8058            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8059                    "Can't grant URI permission for non-content URI: " + grantUri);
8060            return -1;
8061        }
8062
8063        final String authority = grantUri.uri.getAuthority();
8064        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8065                MATCH_DEBUG_TRIAGED_MISSING);
8066        if (pi == null) {
8067            Slog.w(TAG, "No content provider found for permission check: " +
8068                    grantUri.uri.toSafeString());
8069            return -1;
8070        }
8071
8072        int targetUid = lastTargetUid;
8073        if (targetUid < 0 && targetPkg != null) {
8074            try {
8075                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8076                        UserHandle.getUserId(callingUid));
8077                if (targetUid < 0) {
8078                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8079                            "Can't grant URI permission no uid for: " + targetPkg);
8080                    return -1;
8081                }
8082            } catch (RemoteException ex) {
8083                return -1;
8084            }
8085        }
8086
8087        if (targetUid >= 0) {
8088            // First...  does the target actually need this permission?
8089            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8090                // No need to grant the target this permission.
8091                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8092                        "Target " + targetPkg + " already has full permission to " + grantUri);
8093                return -1;
8094            }
8095        } else {
8096            // First...  there is no target package, so can anyone access it?
8097            boolean allowed = pi.exported;
8098            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8099                if (pi.readPermission != null) {
8100                    allowed = false;
8101                }
8102            }
8103            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8104                if (pi.writePermission != null) {
8105                    allowed = false;
8106                }
8107            }
8108            if (allowed) {
8109                return -1;
8110            }
8111        }
8112
8113        /* There is a special cross user grant if:
8114         * - The target is on another user.
8115         * - Apps on the current user can access the uri without any uid permissions.
8116         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8117         * grant uri permissions.
8118         */
8119        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8120                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8121                modeFlags, false /*without considering the uid permissions*/);
8122
8123        // Second...  is the provider allowing granting of URI permissions?
8124        if (!specialCrossUserGrant) {
8125            if (!pi.grantUriPermissions) {
8126                throw new SecurityException("Provider " + pi.packageName
8127                        + "/" + pi.name
8128                        + " does not allow granting of Uri permissions (uri "
8129                        + grantUri + ")");
8130            }
8131            if (pi.uriPermissionPatterns != null) {
8132                final int N = pi.uriPermissionPatterns.length;
8133                boolean allowed = false;
8134                for (int i=0; i<N; i++) {
8135                    if (pi.uriPermissionPatterns[i] != null
8136                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8137                        allowed = true;
8138                        break;
8139                    }
8140                }
8141                if (!allowed) {
8142                    throw new SecurityException("Provider " + pi.packageName
8143                            + "/" + pi.name
8144                            + " does not allow granting of permission to path of Uri "
8145                            + grantUri);
8146                }
8147            }
8148        }
8149
8150        // Third...  does the caller itself have permission to access
8151        // this uri?
8152        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
8153            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8154                // Require they hold a strong enough Uri permission
8155                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8156                    throw new SecurityException("Uid " + callingUid
8157                            + " does not have permission to uri " + grantUri);
8158                }
8159            }
8160        }
8161        return targetUid;
8162    }
8163
8164    /**
8165     * @param uri This uri must NOT contain an embedded userId.
8166     * @param userId The userId in which the uri is to be resolved.
8167     */
8168    @Override
8169    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8170            final int modeFlags, int userId) {
8171        enforceNotIsolatedCaller("checkGrantUriPermission");
8172        synchronized(this) {
8173            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8174                    new GrantUri(userId, uri, false), modeFlags, -1);
8175        }
8176    }
8177
8178    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8179            final int modeFlags, UriPermissionOwner owner) {
8180        if (!Intent.isAccessUriMode(modeFlags)) {
8181            return;
8182        }
8183
8184        // So here we are: the caller has the assumed permission
8185        // to the uri, and the target doesn't.  Let's now give this to
8186        // the target.
8187
8188        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8189                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8190
8191        final String authority = grantUri.uri.getAuthority();
8192        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8193                MATCH_DEBUG_TRIAGED_MISSING);
8194        if (pi == null) {
8195            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8196            return;
8197        }
8198
8199        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8200            grantUri.prefix = true;
8201        }
8202        final UriPermission perm = findOrCreateUriPermissionLocked(
8203                pi.packageName, targetPkg, targetUid, grantUri);
8204        perm.grantModes(modeFlags, owner);
8205    }
8206
8207    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8208            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8209        if (targetPkg == null) {
8210            throw new NullPointerException("targetPkg");
8211        }
8212        int targetUid;
8213        final IPackageManager pm = AppGlobals.getPackageManager();
8214        try {
8215            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8216        } catch (RemoteException ex) {
8217            return;
8218        }
8219
8220        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8221                targetUid);
8222        if (targetUid < 0) {
8223            return;
8224        }
8225
8226        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8227                owner);
8228    }
8229
8230    static class NeededUriGrants extends ArrayList<GrantUri> {
8231        final String targetPkg;
8232        final int targetUid;
8233        final int flags;
8234
8235        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8236            this.targetPkg = targetPkg;
8237            this.targetUid = targetUid;
8238            this.flags = flags;
8239        }
8240    }
8241
8242    /**
8243     * Like checkGrantUriPermissionLocked, but takes an Intent.
8244     */
8245    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8246            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8247        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8248                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8249                + " clip=" + (intent != null ? intent.getClipData() : null)
8250                + " from " + intent + "; flags=0x"
8251                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8252
8253        if (targetPkg == null) {
8254            throw new NullPointerException("targetPkg");
8255        }
8256
8257        if (intent == null) {
8258            return null;
8259        }
8260        Uri data = intent.getData();
8261        ClipData clip = intent.getClipData();
8262        if (data == null && clip == null) {
8263            return null;
8264        }
8265        // Default userId for uris in the intent (if they don't specify it themselves)
8266        int contentUserHint = intent.getContentUserHint();
8267        if (contentUserHint == UserHandle.USER_CURRENT) {
8268            contentUserHint = UserHandle.getUserId(callingUid);
8269        }
8270        final IPackageManager pm = AppGlobals.getPackageManager();
8271        int targetUid;
8272        if (needed != null) {
8273            targetUid = needed.targetUid;
8274        } else {
8275            try {
8276                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8277                        targetUserId);
8278            } catch (RemoteException ex) {
8279                return null;
8280            }
8281            if (targetUid < 0) {
8282                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8283                        "Can't grant URI permission no uid for: " + targetPkg
8284                        + " on user " + targetUserId);
8285                return null;
8286            }
8287        }
8288        if (data != null) {
8289            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8290            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8291                    targetUid);
8292            if (targetUid > 0) {
8293                if (needed == null) {
8294                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8295                }
8296                needed.add(grantUri);
8297            }
8298        }
8299        if (clip != null) {
8300            for (int i=0; i<clip.getItemCount(); i++) {
8301                Uri uri = clip.getItemAt(i).getUri();
8302                if (uri != null) {
8303                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8304                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8305                            targetUid);
8306                    if (targetUid > 0) {
8307                        if (needed == null) {
8308                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8309                        }
8310                        needed.add(grantUri);
8311                    }
8312                } else {
8313                    Intent clipIntent = clip.getItemAt(i).getIntent();
8314                    if (clipIntent != null) {
8315                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8316                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8317                        if (newNeeded != null) {
8318                            needed = newNeeded;
8319                        }
8320                    }
8321                }
8322            }
8323        }
8324
8325        return needed;
8326    }
8327
8328    /**
8329     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8330     */
8331    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8332            UriPermissionOwner owner) {
8333        if (needed != null) {
8334            for (int i=0; i<needed.size(); i++) {
8335                GrantUri grantUri = needed.get(i);
8336                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8337                        grantUri, needed.flags, owner);
8338            }
8339        }
8340    }
8341
8342    void grantUriPermissionFromIntentLocked(int callingUid,
8343            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8344        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8345                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8346        if (needed == null) {
8347            return;
8348        }
8349
8350        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8351    }
8352
8353    /**
8354     * @param uri This uri must NOT contain an embedded userId.
8355     * @param userId The userId in which the uri is to be resolved.
8356     */
8357    @Override
8358    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8359            final int modeFlags, int userId) {
8360        enforceNotIsolatedCaller("grantUriPermission");
8361        GrantUri grantUri = new GrantUri(userId, uri, false);
8362        synchronized(this) {
8363            final ProcessRecord r = getRecordForAppLocked(caller);
8364            if (r == null) {
8365                throw new SecurityException("Unable to find app for caller "
8366                        + caller
8367                        + " when granting permission to uri " + grantUri);
8368            }
8369            if (targetPkg == null) {
8370                throw new IllegalArgumentException("null target");
8371            }
8372            if (grantUri == null) {
8373                throw new IllegalArgumentException("null uri");
8374            }
8375
8376            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8377                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8378                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8379                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8380
8381            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8382                    UserHandle.getUserId(r.uid));
8383        }
8384    }
8385
8386    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8387        if (perm.modeFlags == 0) {
8388            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8389                    perm.targetUid);
8390            if (perms != null) {
8391                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8392                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8393
8394                perms.remove(perm.uri);
8395                if (perms.isEmpty()) {
8396                    mGrantedUriPermissions.remove(perm.targetUid);
8397                }
8398            }
8399        }
8400    }
8401
8402    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8403        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8404                "Revoking all granted permissions to " + grantUri);
8405
8406        final IPackageManager pm = AppGlobals.getPackageManager();
8407        final String authority = grantUri.uri.getAuthority();
8408        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8409                MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8410        if (pi == null) {
8411            Slog.w(TAG, "No content provider found for permission revoke: "
8412                    + grantUri.toSafeString());
8413            return;
8414        }
8415
8416        // Does the caller have this permission on the URI?
8417        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8418            // If they don't have direct access to the URI, then revoke any
8419            // ownerless URI permissions that have been granted to them.
8420            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8421            if (perms != null) {
8422                boolean persistChanged = false;
8423                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8424                    final UriPermission perm = it.next();
8425                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8426                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8427                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8428                                "Revoking non-owned " + perm.targetUid
8429                                + " permission to " + perm.uri);
8430                        persistChanged |= perm.revokeModes(
8431                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8432                        if (perm.modeFlags == 0) {
8433                            it.remove();
8434                        }
8435                    }
8436                }
8437                if (perms.isEmpty()) {
8438                    mGrantedUriPermissions.remove(callingUid);
8439                }
8440                if (persistChanged) {
8441                    schedulePersistUriGrants();
8442                }
8443            }
8444            return;
8445        }
8446
8447        boolean persistChanged = false;
8448
8449        // Go through all of the permissions and remove any that match.
8450        int N = mGrantedUriPermissions.size();
8451        for (int i = 0; i < N; i++) {
8452            final int targetUid = mGrantedUriPermissions.keyAt(i);
8453            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8454
8455            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8456                final UriPermission perm = it.next();
8457                if (perm.uri.sourceUserId == grantUri.sourceUserId
8458                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8459                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8460                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8461                    persistChanged |= perm.revokeModes(
8462                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8463                    if (perm.modeFlags == 0) {
8464                        it.remove();
8465                    }
8466                }
8467            }
8468
8469            if (perms.isEmpty()) {
8470                mGrantedUriPermissions.remove(targetUid);
8471                N--;
8472                i--;
8473            }
8474        }
8475
8476        if (persistChanged) {
8477            schedulePersistUriGrants();
8478        }
8479    }
8480
8481    /**
8482     * @param uri This uri must NOT contain an embedded userId.
8483     * @param userId The userId in which the uri is to be resolved.
8484     */
8485    @Override
8486    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8487            int userId) {
8488        enforceNotIsolatedCaller("revokeUriPermission");
8489        synchronized(this) {
8490            final ProcessRecord r = getRecordForAppLocked(caller);
8491            if (r == null) {
8492                throw new SecurityException("Unable to find app for caller "
8493                        + caller
8494                        + " when revoking permission to uri " + uri);
8495            }
8496            if (uri == null) {
8497                Slog.w(TAG, "revokeUriPermission: null uri");
8498                return;
8499            }
8500
8501            if (!Intent.isAccessUriMode(modeFlags)) {
8502                return;
8503            }
8504
8505            final String authority = uri.getAuthority();
8506            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8507                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8508            if (pi == null) {
8509                Slog.w(TAG, "No content provider found for permission revoke: "
8510                        + uri.toSafeString());
8511                return;
8512            }
8513
8514            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8515        }
8516    }
8517
8518    /**
8519     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8520     * given package.
8521     *
8522     * @param packageName Package name to match, or {@code null} to apply to all
8523     *            packages.
8524     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8525     *            to all users.
8526     * @param persistable If persistable grants should be removed.
8527     */
8528    private void removeUriPermissionsForPackageLocked(
8529            String packageName, int userHandle, boolean persistable) {
8530        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8531            throw new IllegalArgumentException("Must narrow by either package or user");
8532        }
8533
8534        boolean persistChanged = false;
8535
8536        int N = mGrantedUriPermissions.size();
8537        for (int i = 0; i < N; i++) {
8538            final int targetUid = mGrantedUriPermissions.keyAt(i);
8539            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8540
8541            // Only inspect grants matching user
8542            if (userHandle == UserHandle.USER_ALL
8543                    || userHandle == UserHandle.getUserId(targetUid)) {
8544                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8545                    final UriPermission perm = it.next();
8546
8547                    // Only inspect grants matching package
8548                    if (packageName == null || perm.sourcePkg.equals(packageName)
8549                            || perm.targetPkg.equals(packageName)) {
8550                        persistChanged |= perm.revokeModes(persistable
8551                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8552
8553                        // Only remove when no modes remain; any persisted grants
8554                        // will keep this alive.
8555                        if (perm.modeFlags == 0) {
8556                            it.remove();
8557                        }
8558                    }
8559                }
8560
8561                if (perms.isEmpty()) {
8562                    mGrantedUriPermissions.remove(targetUid);
8563                    N--;
8564                    i--;
8565                }
8566            }
8567        }
8568
8569        if (persistChanged) {
8570            schedulePersistUriGrants();
8571        }
8572    }
8573
8574    @Override
8575    public IBinder newUriPermissionOwner(String name) {
8576        enforceNotIsolatedCaller("newUriPermissionOwner");
8577        synchronized(this) {
8578            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8579            return owner.getExternalTokenLocked();
8580        }
8581    }
8582
8583    @Override
8584    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8585        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8586        synchronized(this) {
8587            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8588            if (r == null) {
8589                throw new IllegalArgumentException("Activity does not exist; token="
8590                        + activityToken);
8591            }
8592            return r.getUriPermissionsLocked().getExternalTokenLocked();
8593        }
8594    }
8595    /**
8596     * @param uri This uri must NOT contain an embedded userId.
8597     * @param sourceUserId The userId in which the uri is to be resolved.
8598     * @param targetUserId The userId of the app that receives the grant.
8599     */
8600    @Override
8601    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8602            final int modeFlags, int sourceUserId, int targetUserId) {
8603        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8604                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8605                "grantUriPermissionFromOwner", null);
8606        synchronized(this) {
8607            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8608            if (owner == null) {
8609                throw new IllegalArgumentException("Unknown owner: " + token);
8610            }
8611            if (fromUid != Binder.getCallingUid()) {
8612                if (Binder.getCallingUid() != Process.myUid()) {
8613                    // Only system code can grant URI permissions on behalf
8614                    // of other users.
8615                    throw new SecurityException("nice try");
8616                }
8617            }
8618            if (targetPkg == null) {
8619                throw new IllegalArgumentException("null target");
8620            }
8621            if (uri == null) {
8622                throw new IllegalArgumentException("null uri");
8623            }
8624
8625            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8626                    modeFlags, owner, targetUserId);
8627        }
8628    }
8629
8630    /**
8631     * @param uri This uri must NOT contain an embedded userId.
8632     * @param userId The userId in which the uri is to be resolved.
8633     */
8634    @Override
8635    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8636        synchronized(this) {
8637            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8638            if (owner == null) {
8639                throw new IllegalArgumentException("Unknown owner: " + token);
8640            }
8641
8642            if (uri == null) {
8643                owner.removeUriPermissionsLocked(mode);
8644            } else {
8645                final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
8646                owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
8647            }
8648        }
8649    }
8650
8651    private void schedulePersistUriGrants() {
8652        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8653            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8654                    10 * DateUtils.SECOND_IN_MILLIS);
8655        }
8656    }
8657
8658    private void writeGrantedUriPermissions() {
8659        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8660
8661        // Snapshot permissions so we can persist without lock
8662        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8663        synchronized (this) {
8664            final int size = mGrantedUriPermissions.size();
8665            for (int i = 0; i < size; i++) {
8666                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8667                for (UriPermission perm : perms.values()) {
8668                    if (perm.persistedModeFlags != 0) {
8669                        persist.add(perm.snapshot());
8670                    }
8671                }
8672            }
8673        }
8674
8675        FileOutputStream fos = null;
8676        try {
8677            fos = mGrantFile.startWrite();
8678
8679            XmlSerializer out = new FastXmlSerializer();
8680            out.setOutput(fos, StandardCharsets.UTF_8.name());
8681            out.startDocument(null, true);
8682            out.startTag(null, TAG_URI_GRANTS);
8683            for (UriPermission.Snapshot perm : persist) {
8684                out.startTag(null, TAG_URI_GRANT);
8685                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8686                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8687                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8688                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8689                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8690                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8691                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8692                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8693                out.endTag(null, TAG_URI_GRANT);
8694            }
8695            out.endTag(null, TAG_URI_GRANTS);
8696            out.endDocument();
8697
8698            mGrantFile.finishWrite(fos);
8699        } catch (IOException e) {
8700            if (fos != null) {
8701                mGrantFile.failWrite(fos);
8702            }
8703        }
8704    }
8705
8706    private void readGrantedUriPermissionsLocked() {
8707        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8708
8709        final long now = System.currentTimeMillis();
8710
8711        FileInputStream fis = null;
8712        try {
8713            fis = mGrantFile.openRead();
8714            final XmlPullParser in = Xml.newPullParser();
8715            in.setInput(fis, StandardCharsets.UTF_8.name());
8716
8717            int type;
8718            while ((type = in.next()) != END_DOCUMENT) {
8719                final String tag = in.getName();
8720                if (type == START_TAG) {
8721                    if (TAG_URI_GRANT.equals(tag)) {
8722                        final int sourceUserId;
8723                        final int targetUserId;
8724                        final int userHandle = readIntAttribute(in,
8725                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8726                        if (userHandle != UserHandle.USER_NULL) {
8727                            // For backwards compatibility.
8728                            sourceUserId = userHandle;
8729                            targetUserId = userHandle;
8730                        } else {
8731                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8732                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8733                        }
8734                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8735                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8736                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8737                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8738                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8739                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8740
8741                        // Sanity check that provider still belongs to source package
8742                        // Both direct boot aware and unaware packages are fine as we
8743                        // will do filtering at query time to avoid multiple parsing.
8744                        final ProviderInfo pi = getProviderInfoLocked(
8745                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
8746                                        | MATCH_DIRECT_BOOT_UNAWARE);
8747                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8748                            int targetUid = -1;
8749                            try {
8750                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8751                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8752                            } catch (RemoteException e) {
8753                            }
8754                            if (targetUid != -1) {
8755                                final UriPermission perm = findOrCreateUriPermissionLocked(
8756                                        sourcePkg, targetPkg, targetUid,
8757                                        new GrantUri(sourceUserId, uri, prefix));
8758                                perm.initPersistedModes(modeFlags, createdTime);
8759                            }
8760                        } else {
8761                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8762                                    + " but instead found " + pi);
8763                        }
8764                    }
8765                }
8766            }
8767        } catch (FileNotFoundException e) {
8768            // Missing grants is okay
8769        } catch (IOException e) {
8770            Slog.wtf(TAG, "Failed reading Uri grants", e);
8771        } catch (XmlPullParserException e) {
8772            Slog.wtf(TAG, "Failed reading Uri grants", e);
8773        } finally {
8774            IoUtils.closeQuietly(fis);
8775        }
8776    }
8777
8778    /**
8779     * @param uri This uri must NOT contain an embedded userId.
8780     * @param userId The userId in which the uri is to be resolved.
8781     */
8782    @Override
8783    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8784        enforceNotIsolatedCaller("takePersistableUriPermission");
8785
8786        Preconditions.checkFlagsArgument(modeFlags,
8787                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8788
8789        synchronized (this) {
8790            final int callingUid = Binder.getCallingUid();
8791            boolean persistChanged = false;
8792            GrantUri grantUri = new GrantUri(userId, uri, false);
8793
8794            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8795                    new GrantUri(userId, uri, false));
8796            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8797                    new GrantUri(userId, uri, true));
8798
8799            final boolean exactValid = (exactPerm != null)
8800                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8801            final boolean prefixValid = (prefixPerm != null)
8802                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8803
8804            if (!(exactValid || prefixValid)) {
8805                throw new SecurityException("No persistable permission grants found for UID "
8806                        + callingUid + " and Uri " + grantUri.toSafeString());
8807            }
8808
8809            if (exactValid) {
8810                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8811            }
8812            if (prefixValid) {
8813                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8814            }
8815
8816            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8817
8818            if (persistChanged) {
8819                schedulePersistUriGrants();
8820            }
8821        }
8822    }
8823
8824    /**
8825     * @param uri This uri must NOT contain an embedded userId.
8826     * @param userId The userId in which the uri is to be resolved.
8827     */
8828    @Override
8829    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8830        enforceNotIsolatedCaller("releasePersistableUriPermission");
8831
8832        Preconditions.checkFlagsArgument(modeFlags,
8833                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8834
8835        synchronized (this) {
8836            final int callingUid = Binder.getCallingUid();
8837            boolean persistChanged = false;
8838
8839            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8840                    new GrantUri(userId, uri, false));
8841            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8842                    new GrantUri(userId, uri, true));
8843            if (exactPerm == null && prefixPerm == null) {
8844                throw new SecurityException("No permission grants found for UID " + callingUid
8845                        + " and Uri " + uri.toSafeString());
8846            }
8847
8848            if (exactPerm != null) {
8849                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8850                removeUriPermissionIfNeededLocked(exactPerm);
8851            }
8852            if (prefixPerm != null) {
8853                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8854                removeUriPermissionIfNeededLocked(prefixPerm);
8855            }
8856
8857            if (persistChanged) {
8858                schedulePersistUriGrants();
8859            }
8860        }
8861    }
8862
8863    /**
8864     * Prune any older {@link UriPermission} for the given UID until outstanding
8865     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8866     *
8867     * @return if any mutations occured that require persisting.
8868     */
8869    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8870        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8871        if (perms == null) return false;
8872        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8873
8874        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8875        for (UriPermission perm : perms.values()) {
8876            if (perm.persistedModeFlags != 0) {
8877                persisted.add(perm);
8878            }
8879        }
8880
8881        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8882        if (trimCount <= 0) return false;
8883
8884        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8885        for (int i = 0; i < trimCount; i++) {
8886            final UriPermission perm = persisted.get(i);
8887
8888            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8889                    "Trimming grant created at " + perm.persistedCreateTime);
8890
8891            perm.releasePersistableModes(~0);
8892            removeUriPermissionIfNeededLocked(perm);
8893        }
8894
8895        return true;
8896    }
8897
8898    @Override
8899    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8900            String packageName, boolean incoming) {
8901        enforceNotIsolatedCaller("getPersistedUriPermissions");
8902        Preconditions.checkNotNull(packageName, "packageName");
8903
8904        final int callingUid = Binder.getCallingUid();
8905        final int callingUserId = UserHandle.getUserId(callingUid);
8906        final IPackageManager pm = AppGlobals.getPackageManager();
8907        try {
8908            final int packageUid = pm.getPackageUid(packageName,
8909                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
8910            if (packageUid != callingUid) {
8911                throw new SecurityException(
8912                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8913            }
8914        } catch (RemoteException e) {
8915            throw new SecurityException("Failed to verify package name ownership");
8916        }
8917
8918        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8919        synchronized (this) {
8920            if (incoming) {
8921                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8922                        callingUid);
8923                if (perms == null) {
8924                    Slog.w(TAG, "No permission grants found for " + packageName);
8925                } else {
8926                    for (UriPermission perm : perms.values()) {
8927                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8928                            result.add(perm.buildPersistedPublicApiObject());
8929                        }
8930                    }
8931                }
8932            } else {
8933                final int size = mGrantedUriPermissions.size();
8934                for (int i = 0; i < size; i++) {
8935                    final ArrayMap<GrantUri, UriPermission> perms =
8936                            mGrantedUriPermissions.valueAt(i);
8937                    for (UriPermission perm : perms.values()) {
8938                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8939                            result.add(perm.buildPersistedPublicApiObject());
8940                        }
8941                    }
8942                }
8943            }
8944        }
8945        return new ParceledListSlice<android.content.UriPermission>(result);
8946    }
8947
8948    @Override
8949    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8950            String packageName, int userId) {
8951        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8952                "getGrantedUriPermissions");
8953
8954        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8955        synchronized (this) {
8956            final int size = mGrantedUriPermissions.size();
8957            for (int i = 0; i < size; i++) {
8958                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8959                for (UriPermission perm : perms.values()) {
8960                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8961                            && perm.persistedModeFlags != 0) {
8962                        result.add(perm.buildPersistedPublicApiObject());
8963                    }
8964                }
8965            }
8966        }
8967        return new ParceledListSlice<android.content.UriPermission>(result);
8968    }
8969
8970    @Override
8971    public void clearGrantedUriPermissions(String packageName, int userId) {
8972        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8973                "clearGrantedUriPermissions");
8974        removeUriPermissionsForPackageLocked(packageName, userId, true);
8975    }
8976
8977    @Override
8978    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8979        synchronized (this) {
8980            ProcessRecord app =
8981                who != null ? getRecordForAppLocked(who) : null;
8982            if (app == null) return;
8983
8984            Message msg = Message.obtain();
8985            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8986            msg.obj = app;
8987            msg.arg1 = waiting ? 1 : 0;
8988            mUiHandler.sendMessage(msg);
8989        }
8990    }
8991
8992    @Override
8993    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8994        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8995        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8996        outInfo.availMem = Process.getFreeMemory();
8997        outInfo.totalMem = Process.getTotalMemory();
8998        outInfo.threshold = homeAppMem;
8999        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9000        outInfo.hiddenAppThreshold = cachedAppMem;
9001        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9002                ProcessList.SERVICE_ADJ);
9003        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9004                ProcessList.VISIBLE_APP_ADJ);
9005        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9006                ProcessList.FOREGROUND_APP_ADJ);
9007    }
9008
9009    // =========================================================
9010    // TASK MANAGEMENT
9011    // =========================================================
9012
9013    @Override
9014    public List<IAppTask> getAppTasks(String callingPackage) {
9015        int callingUid = Binder.getCallingUid();
9016        long ident = Binder.clearCallingIdentity();
9017
9018        synchronized(this) {
9019            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
9020            try {
9021                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9022
9023                final int N = mRecentTasks.size();
9024                for (int i = 0; i < N; i++) {
9025                    TaskRecord tr = mRecentTasks.get(i);
9026                    // Skip tasks that do not match the caller.  We don't need to verify
9027                    // callingPackage, because we are also limiting to callingUid and know
9028                    // that will limit to the correct security sandbox.
9029                    if (tr.effectiveUid != callingUid) {
9030                        continue;
9031                    }
9032                    Intent intent = tr.getBaseIntent();
9033                    if (intent == null ||
9034                            !callingPackage.equals(intent.getComponent().getPackageName())) {
9035                        continue;
9036                    }
9037                    ActivityManager.RecentTaskInfo taskInfo =
9038                            createRecentTaskInfoFromTaskRecord(tr);
9039                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9040                    list.add(taskImpl);
9041                }
9042            } finally {
9043                Binder.restoreCallingIdentity(ident);
9044            }
9045            return list;
9046        }
9047    }
9048
9049    @Override
9050    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9051        final int callingUid = Binder.getCallingUid();
9052        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9053
9054        synchronized(this) {
9055            if (DEBUG_ALL) Slog.v(
9056                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9057
9058            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9059                    callingUid);
9060
9061            // TODO: Improve with MRU list from all ActivityStacks.
9062            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9063        }
9064
9065        return list;
9066    }
9067
9068    /**
9069     * Creates a new RecentTaskInfo from a TaskRecord.
9070     */
9071    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9072        // Update the task description to reflect any changes in the task stack
9073        tr.updateTaskDescription();
9074
9075        // Compose the recent task info
9076        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9077        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9078        rti.persistentId = tr.taskId;
9079        rti.baseIntent = new Intent(tr.getBaseIntent());
9080        rti.origActivity = tr.origActivity;
9081        rti.realActivity = tr.realActivity;
9082        rti.description = tr.lastDescription;
9083        rti.stackId = tr.getStackId();
9084        rti.userId = tr.userId;
9085        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9086        rti.firstActiveTime = tr.firstActiveTime;
9087        rti.lastActiveTime = tr.lastActiveTime;
9088        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9089        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9090        rti.numActivities = 0;
9091        if (tr.mBounds != null) {
9092            rti.bounds = new Rect(tr.mBounds);
9093        }
9094        rti.isDockable = tr.canGoInDockedStack();
9095        rti.resizeMode = tr.mResizeMode;
9096
9097        ActivityRecord base = null;
9098        ActivityRecord top = null;
9099        ActivityRecord tmp;
9100
9101        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9102            tmp = tr.mActivities.get(i);
9103            if (tmp.finishing) {
9104                continue;
9105            }
9106            base = tmp;
9107            if (top == null || (top.state == ActivityState.INITIALIZING)) {
9108                top = base;
9109            }
9110            rti.numActivities++;
9111        }
9112
9113        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9114        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9115
9116        return rti;
9117    }
9118
9119    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9120        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9121                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9122        if (!allowed) {
9123            if (checkPermission(android.Manifest.permission.GET_TASKS,
9124                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9125                // Temporary compatibility: some existing apps on the system image may
9126                // still be requesting the old permission and not switched to the new
9127                // one; if so, we'll still allow them full access.  This means we need
9128                // to see if they are holding the old permission and are a system app.
9129                try {
9130                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9131                        allowed = true;
9132                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9133                                + " is using old GET_TASKS but privileged; allowing");
9134                    }
9135                } catch (RemoteException e) {
9136                }
9137            }
9138        }
9139        if (!allowed) {
9140            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9141                    + " does not hold REAL_GET_TASKS; limiting output");
9142        }
9143        return allowed;
9144    }
9145
9146    @Override
9147    public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9148            int userId) {
9149        final int callingUid = Binder.getCallingUid();
9150        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9151                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9152
9153        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9154        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9155        synchronized (this) {
9156            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9157                    callingUid);
9158            final boolean detailed = checkCallingPermission(
9159                    android.Manifest.permission.GET_DETAILED_TASKS)
9160                    == PackageManager.PERMISSION_GRANTED;
9161
9162            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9163                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9164                return ParceledListSlice.emptyList();
9165            }
9166            mRecentTasks.loadUserRecentsLocked(userId);
9167
9168            final int recentsCount = mRecentTasks.size();
9169            ArrayList<ActivityManager.RecentTaskInfo> res =
9170                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9171
9172            final Set<Integer> includedUsers;
9173            if (includeProfiles) {
9174                includedUsers = mUserController.getProfileIds(userId);
9175            } else {
9176                includedUsers = new HashSet<>();
9177            }
9178            includedUsers.add(Integer.valueOf(userId));
9179
9180            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9181                TaskRecord tr = mRecentTasks.get(i);
9182                // Only add calling user or related users recent tasks
9183                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9184                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9185                    continue;
9186                }
9187
9188                if (tr.realActivitySuspended) {
9189                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9190                    continue;
9191                }
9192
9193                // Return the entry if desired by the caller.  We always return
9194                // the first entry, because callers always expect this to be the
9195                // foreground app.  We may filter others if the caller has
9196                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9197                // we should exclude the entry.
9198
9199                if (i == 0
9200                        || withExcluded
9201                        || (tr.intent == null)
9202                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9203                                == 0)) {
9204                    if (!allowed) {
9205                        // If the caller doesn't have the GET_TASKS permission, then only
9206                        // allow them to see a small subset of tasks -- their own and home.
9207                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9208                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9209                            continue;
9210                        }
9211                    }
9212                    final ActivityStack stack = tr.getStack();
9213                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9214                        if (stack != null && stack.isHomeStack()) {
9215                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9216                                    "Skipping, home stack task: " + tr);
9217                            continue;
9218                        }
9219                    }
9220                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9221                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9222                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9223                                    "Skipping, top task in docked stack: " + tr);
9224                            continue;
9225                        }
9226                    }
9227                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9228                        if (stack != null && stack.isPinnedStack()) {
9229                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9230                                    "Skipping, pinned stack task: " + tr);
9231                            continue;
9232                        }
9233                    }
9234                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9235                        // Don't include auto remove tasks that are finished or finishing.
9236                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9237                                "Skipping, auto-remove without activity: " + tr);
9238                        continue;
9239                    }
9240                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9241                            && !tr.isAvailable) {
9242                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9243                                "Skipping, unavail real act: " + tr);
9244                        continue;
9245                    }
9246
9247                    if (!tr.mUserSetupComplete) {
9248                        // Don't include task launched while user is not done setting-up.
9249                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9250                                "Skipping, user setup not complete: " + tr);
9251                        continue;
9252                    }
9253
9254                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9255                    if (!detailed) {
9256                        rti.baseIntent.replaceExtras((Bundle)null);
9257                    }
9258
9259                    res.add(rti);
9260                    maxNum--;
9261                }
9262            }
9263            return new ParceledListSlice<>(res);
9264        }
9265    }
9266
9267    @Override
9268    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9269        synchronized (this) {
9270            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9271                    "getTaskThumbnail()");
9272            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9273                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9274            if (tr != null) {
9275                return tr.getTaskThumbnailLocked();
9276            }
9277        }
9278        return null;
9279    }
9280
9281    @Override
9282    public int addAppTask(IBinder activityToken, Intent intent,
9283            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9284        final int callingUid = Binder.getCallingUid();
9285        final long callingIdent = Binder.clearCallingIdentity();
9286
9287        try {
9288            synchronized (this) {
9289                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9290                if (r == null) {
9291                    throw new IllegalArgumentException("Activity does not exist; token="
9292                            + activityToken);
9293                }
9294                ComponentName comp = intent.getComponent();
9295                if (comp == null) {
9296                    throw new IllegalArgumentException("Intent " + intent
9297                            + " must specify explicit component");
9298                }
9299                if (thumbnail.getWidth() != mThumbnailWidth
9300                        || thumbnail.getHeight() != mThumbnailHeight) {
9301                    throw new IllegalArgumentException("Bad thumbnail size: got "
9302                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9303                            + mThumbnailWidth + "x" + mThumbnailHeight);
9304                }
9305                if (intent.getSelector() != null) {
9306                    intent.setSelector(null);
9307                }
9308                if (intent.getSourceBounds() != null) {
9309                    intent.setSourceBounds(null);
9310                }
9311                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9312                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9313                        // The caller has added this as an auto-remove task...  that makes no
9314                        // sense, so turn off auto-remove.
9315                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9316                    }
9317                }
9318                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9319                    mLastAddedTaskActivity = null;
9320                }
9321                ActivityInfo ainfo = mLastAddedTaskActivity;
9322                if (ainfo == null) {
9323                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9324                            comp, 0, UserHandle.getUserId(callingUid));
9325                    if (ainfo.applicationInfo.uid != callingUid) {
9326                        throw new SecurityException(
9327                                "Can't add task for another application: target uid="
9328                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9329                    }
9330                }
9331
9332                TaskRecord task = new TaskRecord(this,
9333                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9334                        ainfo, intent, description, new TaskThumbnailInfo());
9335
9336                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9337                if (trimIdx >= 0) {
9338                    // If this would have caused a trim, then we'll abort because that
9339                    // means it would be added at the end of the list but then just removed.
9340                    return INVALID_TASK_ID;
9341                }
9342
9343                final int N = mRecentTasks.size();
9344                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9345                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9346                    tr.removedFromRecents();
9347                }
9348
9349                task.inRecents = true;
9350                mRecentTasks.add(task);
9351                r.getStack().addTask(task, false, "addAppTask");
9352
9353                task.setLastThumbnailLocked(thumbnail);
9354                task.freeLastThumbnail();
9355
9356                return task.taskId;
9357            }
9358        } finally {
9359            Binder.restoreCallingIdentity(callingIdent);
9360        }
9361    }
9362
9363    @Override
9364    public Point getAppTaskThumbnailSize() {
9365        synchronized (this) {
9366            return new Point(mThumbnailWidth,  mThumbnailHeight);
9367        }
9368    }
9369
9370    @Override
9371    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9372        synchronized (this) {
9373            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9374            if (r != null) {
9375                r.setTaskDescription(td);
9376                r.task.updateTaskDescription();
9377            }
9378        }
9379    }
9380
9381    @Override
9382    public void setTaskResizeable(int taskId, int resizeableMode) {
9383        synchronized (this) {
9384            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9385                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9386            if (task == null) {
9387                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9388                return;
9389            }
9390            if (task.mResizeMode != resizeableMode) {
9391                task.mResizeMode = resizeableMode;
9392                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9393                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9394                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9395            }
9396        }
9397    }
9398
9399    @Override
9400    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9401        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9402        long ident = Binder.clearCallingIdentity();
9403        try {
9404            synchronized (this) {
9405                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9406                if (task == null) {
9407                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9408                    return;
9409                }
9410                // Place the task in the right stack if it isn't there already based on
9411                // the requested bounds.
9412                // The stack transition logic is:
9413                // - a null bounds on a freeform task moves that task to fullscreen
9414                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9415                //   that task to freeform
9416                // - otherwise the task is not moved
9417                int stackId = task.getStackId();
9418                if (!StackId.isTaskResizeAllowed(stackId)) {
9419                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9420                }
9421                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9422                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9423                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9424                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9425                }
9426                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9427                if (stackId != task.getStackId()) {
9428                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9429                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9430                    preserveWindow = false;
9431                }
9432
9433                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9434                        false /* deferResume */);
9435            }
9436        } finally {
9437            Binder.restoreCallingIdentity(ident);
9438        }
9439    }
9440
9441    @Override
9442    public Rect getTaskBounds(int taskId) {
9443        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9444        long ident = Binder.clearCallingIdentity();
9445        Rect rect = new Rect();
9446        try {
9447            synchronized (this) {
9448                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9449                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9450                if (task == null) {
9451                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9452                    return rect;
9453                }
9454                if (task.getStack() != null) {
9455                    // Return the bounds from window manager since it will be adjusted for various
9456                    // things like the presense of a docked stack for tasks that aren't resizeable.
9457                    mWindowManager.getTaskBounds(task.taskId, rect);
9458                } else {
9459                    // Task isn't in window manager yet since it isn't associated with a stack.
9460                    // Return the persist value from activity manager
9461                    if (task.mBounds != null) {
9462                        rect.set(task.mBounds);
9463                    } else if (task.mLastNonFullscreenBounds != null) {
9464                        rect.set(task.mLastNonFullscreenBounds);
9465                    }
9466                }
9467            }
9468        } finally {
9469            Binder.restoreCallingIdentity(ident);
9470        }
9471        return rect;
9472    }
9473
9474    @Override
9475    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9476        if (userId != UserHandle.getCallingUserId()) {
9477            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9478                    "getTaskDescriptionIcon");
9479        }
9480        final File passedIconFile = new File(filePath);
9481        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9482                passedIconFile.getName());
9483        if (!legitIconFile.getPath().equals(filePath)
9484                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9485            throw new IllegalArgumentException("Bad file path: " + filePath
9486                    + " passed for userId " + userId);
9487        }
9488        return mRecentTasks.getTaskDescriptionIcon(filePath);
9489    }
9490
9491    @Override
9492    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9493            throws RemoteException {
9494        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9495                opts.getCustomInPlaceResId() == 0) {
9496            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9497                    "with valid animation");
9498        }
9499        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9500        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9501                opts.getCustomInPlaceResId());
9502        mWindowManager.executeAppTransition();
9503    }
9504
9505    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9506            boolean removeFromRecents) {
9507        if (removeFromRecents) {
9508            mRecentTasks.remove(tr);
9509            tr.removedFromRecents();
9510        }
9511        ComponentName component = tr.getBaseIntent().getComponent();
9512        if (component == null) {
9513            Slog.w(TAG, "No component for base intent of task: " + tr);
9514            return;
9515        }
9516
9517        // Find any running services associated with this app and stop if needed.
9518        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9519
9520        if (!killProcess) {
9521            return;
9522        }
9523
9524        // Determine if the process(es) for this task should be killed.
9525        final String pkg = component.getPackageName();
9526        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9527        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9528        for (int i = 0; i < pmap.size(); i++) {
9529
9530            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9531            for (int j = 0; j < uids.size(); j++) {
9532                ProcessRecord proc = uids.valueAt(j);
9533                if (proc.userId != tr.userId) {
9534                    // Don't kill process for a different user.
9535                    continue;
9536                }
9537                if (proc == mHomeProcess) {
9538                    // Don't kill the home process along with tasks from the same package.
9539                    continue;
9540                }
9541                if (!proc.pkgList.containsKey(pkg)) {
9542                    // Don't kill process that is not associated with this task.
9543                    continue;
9544                }
9545
9546                for (int k = 0; k < proc.activities.size(); k++) {
9547                    TaskRecord otherTask = proc.activities.get(k).task;
9548                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9549                        // Don't kill process(es) that has an activity in a different task that is
9550                        // also in recents.
9551                        return;
9552                    }
9553                }
9554
9555                if (proc.foregroundServices) {
9556                    // Don't kill process(es) with foreground service.
9557                    return;
9558                }
9559
9560                // Add process to kill list.
9561                procsToKill.add(proc);
9562            }
9563        }
9564
9565        // Kill the running processes.
9566        for (int i = 0; i < procsToKill.size(); i++) {
9567            ProcessRecord pr = procsToKill.get(i);
9568            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9569                    && pr.curReceiver == null) {
9570                pr.kill("remove task", true);
9571            } else {
9572                // We delay killing processes that are not in the background or running a receiver.
9573                pr.waitingToKill = "remove task";
9574            }
9575        }
9576    }
9577
9578    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9579        // Remove all tasks with activities in the specified package from the list of recent tasks
9580        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9581            TaskRecord tr = mRecentTasks.get(i);
9582            if (tr.userId != userId) continue;
9583
9584            ComponentName cn = tr.intent.getComponent();
9585            if (cn != null && cn.getPackageName().equals(packageName)) {
9586                // If the package name matches, remove the task.
9587                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9588            }
9589        }
9590    }
9591
9592    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9593            int userId) {
9594
9595        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9596            TaskRecord tr = mRecentTasks.get(i);
9597            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9598                continue;
9599            }
9600
9601            ComponentName cn = tr.intent.getComponent();
9602            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9603                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9604            if (sameComponent) {
9605                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9606            }
9607        }
9608    }
9609
9610    /**
9611     * Removes the task with the specified task id.
9612     *
9613     * @param taskId Identifier of the task to be removed.
9614     * @param killProcess Kill any process associated with the task if possible.
9615     * @param removeFromRecents Whether to also remove the task from recents.
9616     * @return Returns true if the given task was found and removed.
9617     */
9618    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9619            boolean removeFromRecents) {
9620        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9621                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9622        if (tr != null) {
9623            tr.removeTaskActivitiesLocked();
9624            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9625            if (tr.isPersistable) {
9626                notifyTaskPersisterLocked(null, true);
9627            }
9628            return true;
9629        }
9630        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9631        return false;
9632    }
9633
9634    @Override
9635    public void removeStack(int stackId) {
9636        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9637        if (stackId == HOME_STACK_ID) {
9638            throw new IllegalArgumentException("Removing home stack is not allowed.");
9639        }
9640
9641        synchronized (this) {
9642            final long ident = Binder.clearCallingIdentity();
9643            try {
9644                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9645                if (stack == null) {
9646                    return;
9647                }
9648                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9649                for (int i = tasks.size() - 1; i >= 0; i--) {
9650                    removeTaskByIdLocked(
9651                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9652                }
9653            } finally {
9654                Binder.restoreCallingIdentity(ident);
9655            }
9656        }
9657    }
9658
9659    @Override
9660    public boolean removeTask(int taskId) {
9661        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9662        synchronized (this) {
9663            final long ident = Binder.clearCallingIdentity();
9664            try {
9665                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9666            } finally {
9667                Binder.restoreCallingIdentity(ident);
9668            }
9669        }
9670    }
9671
9672    /**
9673     * TODO: Add mController hook
9674     */
9675    @Override
9676    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9677        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9678
9679        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9680        synchronized(this) {
9681            moveTaskToFrontLocked(taskId, flags, bOptions);
9682        }
9683    }
9684
9685    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9686        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9687
9688        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9689                Binder.getCallingUid(), -1, -1, "Task to front")) {
9690            ActivityOptions.abort(options);
9691            return;
9692        }
9693        final long origId = Binder.clearCallingIdentity();
9694        try {
9695            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9696            if (task == null) {
9697                Slog.d(TAG, "Could not find task for id: "+ taskId);
9698                return;
9699            }
9700            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9701                mStackSupervisor.showLockTaskToast();
9702                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9703                return;
9704            }
9705            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9706            if (prev != null && prev.isRecentsActivity()) {
9707                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9708            }
9709            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9710                    false /* forceNonResizable */);
9711        } finally {
9712            Binder.restoreCallingIdentity(origId);
9713        }
9714        ActivityOptions.abort(options);
9715    }
9716
9717    /**
9718     * Moves an activity, and all of the other activities within the same task, to the bottom
9719     * of the history stack.  The activity's order within the task is unchanged.
9720     *
9721     * @param token A reference to the activity we wish to move
9722     * @param nonRoot If false then this only works if the activity is the root
9723     *                of a task; if true it will work for any activity in a task.
9724     * @return Returns true if the move completed, false if not.
9725     */
9726    @Override
9727    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9728        enforceNotIsolatedCaller("moveActivityTaskToBack");
9729        synchronized(this) {
9730            final long origId = Binder.clearCallingIdentity();
9731            try {
9732                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9733                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9734                if (task != null) {
9735                    if (mStackSupervisor.isLockedTask(task)) {
9736                        mStackSupervisor.showLockTaskToast();
9737                        return false;
9738                    }
9739                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9740                }
9741            } finally {
9742                Binder.restoreCallingIdentity(origId);
9743            }
9744        }
9745        return false;
9746    }
9747
9748    @Override
9749    public void moveTaskBackwards(int task) {
9750        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9751                "moveTaskBackwards()");
9752
9753        synchronized(this) {
9754            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9755                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9756                return;
9757            }
9758            final long origId = Binder.clearCallingIdentity();
9759            moveTaskBackwardsLocked(task);
9760            Binder.restoreCallingIdentity(origId);
9761        }
9762    }
9763
9764    private final void moveTaskBackwardsLocked(int task) {
9765        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9766    }
9767
9768    @Override
9769    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9770            IActivityContainerCallback callback) throws RemoteException {
9771        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9772        synchronized (this) {
9773            if (parentActivityToken == null) {
9774                throw new IllegalArgumentException("parent token must not be null");
9775            }
9776            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9777            if (r == null) {
9778                return null;
9779            }
9780            if (callback == null) {
9781                throw new IllegalArgumentException("callback must not be null");
9782            }
9783            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9784        }
9785    }
9786
9787    @Override
9788    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9789        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9790        synchronized (this) {
9791            mStackSupervisor.deleteActivityContainer(container);
9792        }
9793    }
9794
9795    @Override
9796    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9797        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9798        synchronized (this) {
9799            final int stackId = mStackSupervisor.getNextStackId();
9800            final ActivityStack stack =
9801                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9802            if (stack == null) {
9803                return null;
9804            }
9805            return stack.mActivityContainer;
9806        }
9807    }
9808
9809    @Override
9810    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9811        synchronized (this) {
9812            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9813            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9814                return stack.mActivityContainer.getDisplayId();
9815            }
9816            return Display.DEFAULT_DISPLAY;
9817        }
9818    }
9819
9820    @Override
9821    public int getActivityStackId(IBinder token) throws RemoteException {
9822        synchronized (this) {
9823            ActivityStack stack = ActivityRecord.getStackLocked(token);
9824            if (stack == null) {
9825                return INVALID_STACK_ID;
9826            }
9827            return stack.mStackId;
9828        }
9829    }
9830
9831    @Override
9832    public void exitFreeformMode(IBinder token) throws RemoteException {
9833        synchronized (this) {
9834            long ident = Binder.clearCallingIdentity();
9835            try {
9836                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9837                if (r == null) {
9838                    throw new IllegalArgumentException(
9839                            "exitFreeformMode: No activity record matching token=" + token);
9840                }
9841                final ActivityStack stack = r.getStackLocked(token);
9842                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9843                    throw new IllegalStateException(
9844                            "exitFreeformMode: You can only go fullscreen from freeform.");
9845                }
9846                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9847                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9848                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9849            } finally {
9850                Binder.restoreCallingIdentity(ident);
9851            }
9852        }
9853    }
9854
9855    @Override
9856    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9857        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9858        if (stackId == HOME_STACK_ID) {
9859            throw new IllegalArgumentException(
9860                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9861        }
9862        synchronized (this) {
9863            long ident = Binder.clearCallingIdentity();
9864            try {
9865                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9866                        + " to stackId=" + stackId + " toTop=" + toTop);
9867                if (stackId == DOCKED_STACK_ID) {
9868                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9869                            null /* initialBounds */);
9870                }
9871                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9872                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9873                if (result && stackId == DOCKED_STACK_ID) {
9874                    // If task moved to docked stack - show recents if needed.
9875                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9876                            "moveTaskToDockedStack");
9877                }
9878            } finally {
9879                Binder.restoreCallingIdentity(ident);
9880            }
9881        }
9882    }
9883
9884    @Override
9885    public void swapDockedAndFullscreenStack() throws RemoteException {
9886        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9887        synchronized (this) {
9888            long ident = Binder.clearCallingIdentity();
9889            try {
9890                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9891                        FULLSCREEN_WORKSPACE_STACK_ID);
9892                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9893                        : null;
9894                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9895                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9896                        : null;
9897                if (topTask == null || tasks == null || tasks.size() == 0) {
9898                    Slog.w(TAG,
9899                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9900                    return;
9901                }
9902
9903                // TODO: App transition
9904                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9905
9906                // Defer the resume so resume/pausing while moving stacks is dangerous.
9907                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9908                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9909                        ANIMATE, true /* deferResume */);
9910                final int size = tasks.size();
9911                for (int i = 0; i < size; i++) {
9912                    final int id = tasks.get(i).taskId;
9913                    if (id == topTask.taskId) {
9914                        continue;
9915                    }
9916                    mStackSupervisor.moveTaskToStackLocked(id,
9917                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9918                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9919                }
9920
9921                // Because we deferred the resume, to avoid conflicts with stack switches while
9922                // resuming, we need to do it after all the tasks are moved.
9923                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9924                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9925
9926                mWindowManager.executeAppTransition();
9927            } finally {
9928                Binder.restoreCallingIdentity(ident);
9929            }
9930        }
9931    }
9932
9933    /**
9934     * Moves the input task to the docked stack.
9935     *
9936     * @param taskId Id of task to move.
9937     * @param createMode The mode the docked stack should be created in if it doesn't exist
9938     *                   already. See
9939     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9940     *                   and
9941     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9942     * @param toTop If the task and stack should be moved to the top.
9943     * @param animate Whether we should play an animation for the moving the task
9944     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9945     *                      docked stack. Pass {@code null} to use default bounds.
9946     */
9947    @Override
9948    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9949            Rect initialBounds, boolean moveHomeStackFront) {
9950        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9951        synchronized (this) {
9952            long ident = Binder.clearCallingIdentity();
9953            try {
9954                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9955                        + " to createMode=" + createMode + " toTop=" + toTop);
9956                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9957                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9958                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9959                        animate, DEFER_RESUME);
9960                if (moved) {
9961                    if (moveHomeStackFront) {
9962                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9963                    }
9964                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9965                }
9966                return moved;
9967            } finally {
9968                Binder.restoreCallingIdentity(ident);
9969            }
9970        }
9971    }
9972
9973    /**
9974     * Moves the top activity in the input stackId to the pinned stack.
9975     *
9976     * @param stackId Id of stack to move the top activity to pinned stack.
9977     * @param bounds Bounds to use for pinned stack.
9978     *
9979     * @return True if the top activity of the input stack was successfully moved to the pinned
9980     *          stack.
9981     */
9982    @Override
9983    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9984        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9985        synchronized (this) {
9986            if (!mSupportsPictureInPicture) {
9987                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9988                        + "Device doesn't support picture-in-pciture mode");
9989            }
9990
9991            long ident = Binder.clearCallingIdentity();
9992            try {
9993                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9994            } finally {
9995                Binder.restoreCallingIdentity(ident);
9996            }
9997        }
9998    }
9999
10000    @Override
10001    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
10002            boolean preserveWindows, boolean animate, int animationDuration) {
10003        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10004        long ident = Binder.clearCallingIdentity();
10005        try {
10006            synchronized (this) {
10007                if (animate) {
10008                    if (stackId == PINNED_STACK_ID) {
10009                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
10010                    } else {
10011                        throw new IllegalArgumentException("Stack: " + stackId
10012                                + " doesn't support animated resize.");
10013                    }
10014                } else {
10015                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
10016                            null /* tempTaskInsetBounds */, preserveWindows,
10017                            allowResizeInDockedMode, !DEFER_RESUME);
10018                }
10019            }
10020        } finally {
10021            Binder.restoreCallingIdentity(ident);
10022        }
10023    }
10024
10025    @Override
10026    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10027            Rect tempDockedTaskInsetBounds,
10028            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10029        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10030                "resizeDockedStack()");
10031        long ident = Binder.clearCallingIdentity();
10032        try {
10033            synchronized (this) {
10034                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10035                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10036                        PRESERVE_WINDOWS);
10037            }
10038        } finally {
10039            Binder.restoreCallingIdentity(ident);
10040        }
10041    }
10042
10043    @Override
10044    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10045        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10046                "resizePinnedStack()");
10047        final long ident = Binder.clearCallingIdentity();
10048        try {
10049            synchronized (this) {
10050                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10051            }
10052        } finally {
10053            Binder.restoreCallingIdentity(ident);
10054        }
10055    }
10056
10057    @Override
10058    public void positionTaskInStack(int taskId, int stackId, int position) {
10059        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10060        if (stackId == HOME_STACK_ID) {
10061            throw new IllegalArgumentException(
10062                    "positionTaskInStack: Attempt to change the position of task "
10063                    + taskId + " in/to home stack");
10064        }
10065        synchronized (this) {
10066            long ident = Binder.clearCallingIdentity();
10067            try {
10068                if (DEBUG_STACK) Slog.d(TAG_STACK,
10069                        "positionTaskInStack: positioning task=" + taskId
10070                        + " in stackId=" + stackId + " at position=" + position);
10071                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
10072            } finally {
10073                Binder.restoreCallingIdentity(ident);
10074            }
10075        }
10076    }
10077
10078    @Override
10079    public List<StackInfo> getAllStackInfos() {
10080        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10081        long ident = Binder.clearCallingIdentity();
10082        try {
10083            synchronized (this) {
10084                return mStackSupervisor.getAllStackInfosLocked();
10085            }
10086        } finally {
10087            Binder.restoreCallingIdentity(ident);
10088        }
10089    }
10090
10091    @Override
10092    public StackInfo getStackInfo(int stackId) {
10093        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10094        long ident = Binder.clearCallingIdentity();
10095        try {
10096            synchronized (this) {
10097                return mStackSupervisor.getStackInfoLocked(stackId);
10098            }
10099        } finally {
10100            Binder.restoreCallingIdentity(ident);
10101        }
10102    }
10103
10104    @Override
10105    public boolean isInHomeStack(int taskId) {
10106        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10107        long ident = Binder.clearCallingIdentity();
10108        try {
10109            synchronized (this) {
10110                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10111                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
10112                final ActivityStack stack = tr != null ? tr.getStack() : null;
10113                return stack != null && stack.isHomeStack();
10114            }
10115        } finally {
10116            Binder.restoreCallingIdentity(ident);
10117        }
10118    }
10119
10120    @Override
10121    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10122        synchronized(this) {
10123            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10124        }
10125    }
10126
10127    @Override
10128    public void updateDeviceOwner(String packageName) {
10129        final int callingUid = Binder.getCallingUid();
10130        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10131            throw new SecurityException("updateDeviceOwner called from non-system process");
10132        }
10133        synchronized (this) {
10134            mDeviceOwnerName = packageName;
10135        }
10136    }
10137
10138    @Override
10139    public void updateLockTaskPackages(int userId, String[] packages) {
10140        final int callingUid = Binder.getCallingUid();
10141        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10142            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10143                    "updateLockTaskPackages()");
10144        }
10145        synchronized (this) {
10146            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10147                    Arrays.toString(packages));
10148            mLockTaskPackages.put(userId, packages);
10149            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10150        }
10151    }
10152
10153
10154    void startLockTaskModeLocked(TaskRecord task) {
10155        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10156        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10157            return;
10158        }
10159
10160        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10161        // is initiated by system after the pinning request was shown and locked mode is initiated
10162        // by an authorized app directly
10163        final int callingUid = Binder.getCallingUid();
10164        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10165        long ident = Binder.clearCallingIdentity();
10166        try {
10167            if (!isSystemInitiated) {
10168                task.mLockTaskUid = callingUid;
10169                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10170                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10171                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10172                    StatusBarManagerInternal statusBarManager =
10173                            LocalServices.getService(StatusBarManagerInternal.class);
10174                    if (statusBarManager != null) {
10175                        statusBarManager.showScreenPinningRequest(task.taskId);
10176                    }
10177                    return;
10178                }
10179
10180                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10181                if (stack == null || task != stack.topTask()) {
10182                    throw new IllegalArgumentException("Invalid task, not in foreground");
10183                }
10184            }
10185            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10186                    "Locking fully");
10187            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10188                    ActivityManager.LOCK_TASK_MODE_PINNED :
10189                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10190                    "startLockTask", true);
10191        } finally {
10192            Binder.restoreCallingIdentity(ident);
10193        }
10194    }
10195
10196    @Override
10197    public void startLockTaskMode(int taskId) {
10198        synchronized (this) {
10199            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10200            if (task != null) {
10201                startLockTaskModeLocked(task);
10202            }
10203        }
10204    }
10205
10206    @Override
10207    public void startLockTaskMode(IBinder token) {
10208        synchronized (this) {
10209            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10210            if (r == null) {
10211                return;
10212            }
10213            final TaskRecord task = r.task;
10214            if (task != null) {
10215                startLockTaskModeLocked(task);
10216            }
10217        }
10218    }
10219
10220    @Override
10221    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10222        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10223        // This makes inner call to look as if it was initiated by system.
10224        long ident = Binder.clearCallingIdentity();
10225        try {
10226            synchronized (this) {
10227                startLockTaskMode(taskId);
10228            }
10229        } finally {
10230            Binder.restoreCallingIdentity(ident);
10231        }
10232    }
10233
10234    @Override
10235    public void stopLockTaskMode() {
10236        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10237        if (lockTask == null) {
10238            // Our work here is done.
10239            return;
10240        }
10241
10242        final int callingUid = Binder.getCallingUid();
10243        final int lockTaskUid = lockTask.mLockTaskUid;
10244        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10245        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10246            // Done.
10247            return;
10248        } else {
10249            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10250            // It is possible lockTaskMode was started by the system process because
10251            // android:lockTaskMode is set to a locking value in the application manifest
10252            // instead of the app calling startLockTaskMode. In this case
10253            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10254            // {@link TaskRecord.effectiveUid} instead. Also caller with
10255            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10256            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10257                    && callingUid != lockTaskUid
10258                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10259                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10260                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10261            }
10262        }
10263        long ident = Binder.clearCallingIdentity();
10264        try {
10265            Log.d(TAG, "stopLockTaskMode");
10266            // Stop lock task
10267            synchronized (this) {
10268                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10269                        "stopLockTask", true);
10270            }
10271            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10272            if (tm != null) {
10273                tm.showInCallScreen(false);
10274            }
10275        } finally {
10276            Binder.restoreCallingIdentity(ident);
10277        }
10278    }
10279
10280    /**
10281     * This API should be called by SystemUI only when user perform certain action to dismiss
10282     * lock task mode. We should only dismiss pinned lock task mode in this case.
10283     */
10284    @Override
10285    public void stopSystemLockTaskMode() throws RemoteException {
10286        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10287            stopLockTaskMode();
10288        } else {
10289            mStackSupervisor.showLockTaskToast();
10290        }
10291    }
10292
10293    @Override
10294    public boolean isInLockTaskMode() {
10295        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10296    }
10297
10298    @Override
10299    public int getLockTaskModeState() {
10300        synchronized (this) {
10301            return mStackSupervisor.getLockTaskModeState();
10302        }
10303    }
10304
10305    @Override
10306    public void showLockTaskEscapeMessage(IBinder token) {
10307        synchronized (this) {
10308            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10309            if (r == null) {
10310                return;
10311            }
10312            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10313        }
10314    }
10315
10316    // =========================================================
10317    // CONTENT PROVIDERS
10318    // =========================================================
10319
10320    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10321        List<ProviderInfo> providers = null;
10322        try {
10323            providers = AppGlobals.getPackageManager()
10324                    .queryContentProviders(app.processName, app.uid,
10325                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10326                                    | MATCH_DEBUG_TRIAGED_MISSING)
10327                    .getList();
10328        } catch (RemoteException ex) {
10329        }
10330        if (DEBUG_MU) Slog.v(TAG_MU,
10331                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10332        int userId = app.userId;
10333        if (providers != null) {
10334            int N = providers.size();
10335            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10336            for (int i=0; i<N; i++) {
10337                // TODO: keep logic in sync with installEncryptionUnawareProviders
10338                ProviderInfo cpi =
10339                    (ProviderInfo)providers.get(i);
10340                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10341                        cpi.name, cpi.flags);
10342                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10343                    // This is a singleton provider, but a user besides the
10344                    // default user is asking to initialize a process it runs
10345                    // in...  well, no, it doesn't actually run in this process,
10346                    // it runs in the process of the default user.  Get rid of it.
10347                    providers.remove(i);
10348                    N--;
10349                    i--;
10350                    continue;
10351                }
10352
10353                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10354                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10355                if (cpr == null) {
10356                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10357                    mProviderMap.putProviderByClass(comp, cpr);
10358                }
10359                if (DEBUG_MU) Slog.v(TAG_MU,
10360                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10361                app.pubProviders.put(cpi.name, cpr);
10362                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10363                    // Don't add this if it is a platform component that is marked
10364                    // to run in multiple processes, because this is actually
10365                    // part of the framework so doesn't make sense to track as a
10366                    // separate apk in the process.
10367                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10368                            mProcessStats);
10369                }
10370                notifyPackageUse(cpi.applicationInfo.packageName,
10371                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10372            }
10373        }
10374        return providers;
10375    }
10376
10377    /**
10378     * Check if {@link ProcessRecord} has a possible chance at accessing the
10379     * given {@link ProviderInfo}. Final permission checking is always done
10380     * in {@link ContentProvider}.
10381     */
10382    private final String checkContentProviderPermissionLocked(
10383            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10384        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10385        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10386        boolean checkedGrants = false;
10387        if (checkUser) {
10388            // Looking for cross-user grants before enforcing the typical cross-users permissions
10389            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10390            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10391                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10392                    return null;
10393                }
10394                checkedGrants = true;
10395            }
10396            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10397                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10398            if (userId != tmpTargetUserId) {
10399                // When we actually went to determine the final targer user ID, this ended
10400                // up different than our initial check for the authority.  This is because
10401                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10402                // SELF.  So we need to re-check the grants again.
10403                checkedGrants = false;
10404            }
10405        }
10406        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10407                cpi.applicationInfo.uid, cpi.exported)
10408                == PackageManager.PERMISSION_GRANTED) {
10409            return null;
10410        }
10411        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10412                cpi.applicationInfo.uid, cpi.exported)
10413                == PackageManager.PERMISSION_GRANTED) {
10414            return null;
10415        }
10416
10417        PathPermission[] pps = cpi.pathPermissions;
10418        if (pps != null) {
10419            int i = pps.length;
10420            while (i > 0) {
10421                i--;
10422                PathPermission pp = pps[i];
10423                String pprperm = pp.getReadPermission();
10424                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10425                        cpi.applicationInfo.uid, cpi.exported)
10426                        == PackageManager.PERMISSION_GRANTED) {
10427                    return null;
10428                }
10429                String ppwperm = pp.getWritePermission();
10430                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10431                        cpi.applicationInfo.uid, cpi.exported)
10432                        == PackageManager.PERMISSION_GRANTED) {
10433                    return null;
10434                }
10435            }
10436        }
10437        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10438            return null;
10439        }
10440
10441        String msg;
10442        if (!cpi.exported) {
10443            msg = "Permission Denial: opening provider " + cpi.name
10444                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10445                    + ", uid=" + callingUid + ") that is not exported from uid "
10446                    + cpi.applicationInfo.uid;
10447        } else {
10448            msg = "Permission Denial: opening provider " + cpi.name
10449                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10450                    + ", uid=" + callingUid + ") requires "
10451                    + cpi.readPermission + " or " + cpi.writePermission;
10452        }
10453        Slog.w(TAG, msg);
10454        return msg;
10455    }
10456
10457    /**
10458     * Returns if the ContentProvider has granted a uri to callingUid
10459     */
10460    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10461        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10462        if (perms != null) {
10463            for (int i=perms.size()-1; i>=0; i--) {
10464                GrantUri grantUri = perms.keyAt(i);
10465                if (grantUri.sourceUserId == userId || !checkUser) {
10466                    if (matchesProvider(grantUri.uri, cpi)) {
10467                        return true;
10468                    }
10469                }
10470            }
10471        }
10472        return false;
10473    }
10474
10475    /**
10476     * Returns true if the uri authority is one of the authorities specified in the provider.
10477     */
10478    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10479        String uriAuth = uri.getAuthority();
10480        String cpiAuth = cpi.authority;
10481        if (cpiAuth.indexOf(';') == -1) {
10482            return cpiAuth.equals(uriAuth);
10483        }
10484        String[] cpiAuths = cpiAuth.split(";");
10485        int length = cpiAuths.length;
10486        for (int i = 0; i < length; i++) {
10487            if (cpiAuths[i].equals(uriAuth)) return true;
10488        }
10489        return false;
10490    }
10491
10492    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10493            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10494        if (r != null) {
10495            for (int i=0; i<r.conProviders.size(); i++) {
10496                ContentProviderConnection conn = r.conProviders.get(i);
10497                if (conn.provider == cpr) {
10498                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10499                            "Adding provider requested by "
10500                            + r.processName + " from process "
10501                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10502                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10503                    if (stable) {
10504                        conn.stableCount++;
10505                        conn.numStableIncs++;
10506                    } else {
10507                        conn.unstableCount++;
10508                        conn.numUnstableIncs++;
10509                    }
10510                    return conn;
10511                }
10512            }
10513            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10514            if (stable) {
10515                conn.stableCount = 1;
10516                conn.numStableIncs = 1;
10517            } else {
10518                conn.unstableCount = 1;
10519                conn.numUnstableIncs = 1;
10520            }
10521            cpr.connections.add(conn);
10522            r.conProviders.add(conn);
10523            startAssociationLocked(r.uid, r.processName, r.curProcState,
10524                    cpr.uid, cpr.name, cpr.info.processName);
10525            return conn;
10526        }
10527        cpr.addExternalProcessHandleLocked(externalProcessToken);
10528        return null;
10529    }
10530
10531    boolean decProviderCountLocked(ContentProviderConnection conn,
10532            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10533        if (conn != null) {
10534            cpr = conn.provider;
10535            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10536                    "Removing provider requested by "
10537                    + conn.client.processName + " from process "
10538                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10539                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10540            if (stable) {
10541                conn.stableCount--;
10542            } else {
10543                conn.unstableCount--;
10544            }
10545            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10546                cpr.connections.remove(conn);
10547                conn.client.conProviders.remove(conn);
10548                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10549                    // The client is more important than last activity -- note the time this
10550                    // is happening, so we keep the old provider process around a bit as last
10551                    // activity to avoid thrashing it.
10552                    if (cpr.proc != null) {
10553                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10554                    }
10555                }
10556                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10557                return true;
10558            }
10559            return false;
10560        }
10561        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10562        return false;
10563    }
10564
10565    private void checkTime(long startTime, String where) {
10566        long now = SystemClock.uptimeMillis();
10567        if ((now-startTime) > 50) {
10568            // If we are taking more than 50ms, log about it.
10569            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10570        }
10571    }
10572
10573    private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
10574            PROC_SPACE_TERM,
10575            PROC_SPACE_TERM|PROC_PARENS,
10576            PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
10577    };
10578
10579    private final long[] mProcessStateStatsLongs = new long[1];
10580
10581    boolean isProcessAliveLocked(ProcessRecord proc) {
10582        if (proc.procStatFile == null) {
10583            proc.procStatFile = "/proc/" + proc.pid + "/stat";
10584        }
10585        mProcessStateStatsLongs[0] = 0;
10586        if (!Process.readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
10587                mProcessStateStatsLongs, null)) {
10588            if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
10589            return false;
10590        }
10591        final long state = mProcessStateStatsLongs[0];
10592        if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
10593                + (char)state);
10594        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
10595    }
10596
10597    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10598            String name, IBinder token, boolean stable, int userId) {
10599        ContentProviderRecord cpr;
10600        ContentProviderConnection conn = null;
10601        ProviderInfo cpi = null;
10602
10603        synchronized(this) {
10604            long startTime = SystemClock.uptimeMillis();
10605
10606            ProcessRecord r = null;
10607            if (caller != null) {
10608                r = getRecordForAppLocked(caller);
10609                if (r == null) {
10610                    throw new SecurityException(
10611                            "Unable to find app for caller " + caller
10612                          + " (pid=" + Binder.getCallingPid()
10613                          + ") when getting content provider " + name);
10614                }
10615            }
10616
10617            boolean checkCrossUser = true;
10618
10619            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10620
10621            // First check if this content provider has been published...
10622            cpr = mProviderMap.getProviderByName(name, userId);
10623            // If that didn't work, check if it exists for user 0 and then
10624            // verify that it's a singleton provider before using it.
10625            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10626                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10627                if (cpr != null) {
10628                    cpi = cpr.info;
10629                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10630                            cpi.name, cpi.flags)
10631                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10632                        userId = UserHandle.USER_SYSTEM;
10633                        checkCrossUser = false;
10634                    } else {
10635                        cpr = null;
10636                        cpi = null;
10637                    }
10638                }
10639            }
10640
10641            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
10642            if (providerRunning) {
10643                cpi = cpr.info;
10644                String msg;
10645                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10646                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10647                        != null) {
10648                    throw new SecurityException(msg);
10649                }
10650                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10651
10652                if (r != null && cpr.canRunHere(r)) {
10653                    // This provider has been published or is in the process
10654                    // of being published...  but it is also allowed to run
10655                    // in the caller's process, so don't make a connection
10656                    // and just let the caller instantiate its own instance.
10657                    ContentProviderHolder holder = cpr.newHolder(null);
10658                    // don't give caller the provider object, it needs
10659                    // to make its own.
10660                    holder.provider = null;
10661                    return holder;
10662                }
10663
10664                final long origId = Binder.clearCallingIdentity();
10665
10666                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10667
10668                // In this case the provider instance already exists, so we can
10669                // return it right away.
10670                conn = incProviderCountLocked(r, cpr, token, stable);
10671                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10672                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10673                        // If this is a perceptible app accessing the provider,
10674                        // make sure to count it as being accessed and thus
10675                        // back up on the LRU list.  This is good because
10676                        // content providers are often expensive to start.
10677                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10678                        updateLruProcessLocked(cpr.proc, false, null);
10679                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10680                    }
10681                }
10682
10683                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10684                final int verifiedAdj = cpr.proc.verifiedAdj;
10685                boolean success = updateOomAdjLocked(cpr.proc);
10686                // XXX things have changed so updateOomAdjLocked doesn't actually tell us
10687                // if the process has been successfully adjusted.  So to reduce races with
10688                // it, we will check whether the process still exists.  Note that this doesn't
10689                // completely get rid of races with LMK killing the process, but should make
10690                // them much smaller.
10691                if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
10692                    success = false;
10693                }
10694                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10695                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10696                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10697                // NOTE: there is still a race here where a signal could be
10698                // pending on the process even though we managed to update its
10699                // adj level.  Not sure what to do about this, but at least
10700                // the race is now smaller.
10701                if (!success) {
10702                    // Uh oh...  it looks like the provider's process
10703                    // has been killed on us.  We need to wait for a new
10704                    // process to be started, and make sure its death
10705                    // doesn't kill our process.
10706                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10707                            + " is crashing; detaching " + r);
10708                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10709                    checkTime(startTime, "getContentProviderImpl: before appDied");
10710                    appDiedLocked(cpr.proc);
10711                    checkTime(startTime, "getContentProviderImpl: after appDied");
10712                    if (!lastRef) {
10713                        // This wasn't the last ref our process had on
10714                        // the provider...  we have now been killed, bail.
10715                        return null;
10716                    }
10717                    providerRunning = false;
10718                    conn = null;
10719                } else {
10720                    cpr.proc.verifiedAdj = cpr.proc.setAdj;
10721                }
10722
10723                Binder.restoreCallingIdentity(origId);
10724            }
10725
10726            if (!providerRunning) {
10727                try {
10728                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10729                    cpi = AppGlobals.getPackageManager().
10730                        resolveContentProvider(name,
10731                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10732                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10733                } catch (RemoteException ex) {
10734                }
10735                if (cpi == null) {
10736                    return null;
10737                }
10738                // If the provider is a singleton AND
10739                // (it's a call within the same user || the provider is a
10740                // privileged app)
10741                // Then allow connecting to the singleton provider
10742                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10743                        cpi.name, cpi.flags)
10744                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10745                if (singleton) {
10746                    userId = UserHandle.USER_SYSTEM;
10747                }
10748                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10749                checkTime(startTime, "getContentProviderImpl: got app info for user");
10750
10751                String msg;
10752                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10753                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10754                        != null) {
10755                    throw new SecurityException(msg);
10756                }
10757                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10758
10759                if (!mProcessesReady
10760                        && !cpi.processName.equals("system")) {
10761                    // If this content provider does not run in the system
10762                    // process, and the system is not yet ready to run other
10763                    // processes, then fail fast instead of hanging.
10764                    throw new IllegalArgumentException(
10765                            "Attempt to launch content provider before system ready");
10766                }
10767
10768                // Make sure that the user who owns this provider is running.  If not,
10769                // we don't want to allow it to run.
10770                if (!mUserController.isUserRunningLocked(userId, 0)) {
10771                    Slog.w(TAG, "Unable to launch app "
10772                            + cpi.applicationInfo.packageName + "/"
10773                            + cpi.applicationInfo.uid + " for provider "
10774                            + name + ": user " + userId + " is stopped");
10775                    return null;
10776                }
10777
10778                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10779                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10780                cpr = mProviderMap.getProviderByClass(comp, userId);
10781                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10782                final boolean firstClass = cpr == null;
10783                if (firstClass) {
10784                    final long ident = Binder.clearCallingIdentity();
10785
10786                    // If permissions need a review before any of the app components can run,
10787                    // we return no provider and launch a review activity if the calling app
10788                    // is in the foreground.
10789                    if (mPermissionReviewRequired) {
10790                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10791                            return null;
10792                        }
10793                    }
10794
10795                    try {
10796                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10797                        ApplicationInfo ai =
10798                            AppGlobals.getPackageManager().
10799                                getApplicationInfo(
10800                                        cpi.applicationInfo.packageName,
10801                                        STOCK_PM_FLAGS, userId);
10802                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10803                        if (ai == null) {
10804                            Slog.w(TAG, "No package info for content provider "
10805                                    + cpi.name);
10806                            return null;
10807                        }
10808                        ai = getAppInfoForUser(ai, userId);
10809                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10810                    } catch (RemoteException ex) {
10811                        // pm is in same process, this will never happen.
10812                    } finally {
10813                        Binder.restoreCallingIdentity(ident);
10814                    }
10815                }
10816
10817                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10818
10819                if (r != null && cpr.canRunHere(r)) {
10820                    // If this is a multiprocess provider, then just return its
10821                    // info and allow the caller to instantiate it.  Only do
10822                    // this if the provider is the same user as the caller's
10823                    // process, or can run as root (so can be in any process).
10824                    return cpr.newHolder(null);
10825                }
10826
10827                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10828                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10829                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10830
10831                // This is single process, and our app is now connecting to it.
10832                // See if we are already in the process of launching this
10833                // provider.
10834                final int N = mLaunchingProviders.size();
10835                int i;
10836                for (i = 0; i < N; i++) {
10837                    if (mLaunchingProviders.get(i) == cpr) {
10838                        break;
10839                    }
10840                }
10841
10842                // If the provider is not already being launched, then get it
10843                // started.
10844                if (i >= N) {
10845                    final long origId = Binder.clearCallingIdentity();
10846
10847                    try {
10848                        // Content provider is now in use, its package can't be stopped.
10849                        try {
10850                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10851                            AppGlobals.getPackageManager().setPackageStoppedState(
10852                                    cpr.appInfo.packageName, false, userId);
10853                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10854                        } catch (RemoteException e) {
10855                        } catch (IllegalArgumentException e) {
10856                            Slog.w(TAG, "Failed trying to unstop package "
10857                                    + cpr.appInfo.packageName + ": " + e);
10858                        }
10859
10860                        // Use existing process if already started
10861                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10862                        ProcessRecord proc = getProcessRecordLocked(
10863                                cpi.processName, cpr.appInfo.uid, false);
10864                        if (proc != null && proc.thread != null && !proc.killed) {
10865                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10866                                    "Installing in existing process " + proc);
10867                            if (!proc.pubProviders.containsKey(cpi.name)) {
10868                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10869                                proc.pubProviders.put(cpi.name, cpr);
10870                                try {
10871                                    proc.thread.scheduleInstallProvider(cpi);
10872                                } catch (RemoteException e) {
10873                                }
10874                            }
10875                        } else {
10876                            checkTime(startTime, "getContentProviderImpl: before start process");
10877                            proc = startProcessLocked(cpi.processName,
10878                                    cpr.appInfo, false, 0, "content provider",
10879                                    new ComponentName(cpi.applicationInfo.packageName,
10880                                            cpi.name), false, false, false);
10881                            checkTime(startTime, "getContentProviderImpl: after start process");
10882                            if (proc == null) {
10883                                Slog.w(TAG, "Unable to launch app "
10884                                        + cpi.applicationInfo.packageName + "/"
10885                                        + cpi.applicationInfo.uid + " for provider "
10886                                        + name + ": process is bad");
10887                                return null;
10888                            }
10889                        }
10890                        cpr.launchingApp = proc;
10891                        mLaunchingProviders.add(cpr);
10892                    } finally {
10893                        Binder.restoreCallingIdentity(origId);
10894                    }
10895                }
10896
10897                checkTime(startTime, "getContentProviderImpl: updating data structures");
10898
10899                // Make sure the provider is published (the same provider class
10900                // may be published under multiple names).
10901                if (firstClass) {
10902                    mProviderMap.putProviderByClass(comp, cpr);
10903                }
10904
10905                mProviderMap.putProviderByName(name, cpr);
10906                conn = incProviderCountLocked(r, cpr, token, stable);
10907                if (conn != null) {
10908                    conn.waiting = true;
10909                }
10910            }
10911            checkTime(startTime, "getContentProviderImpl: done!");
10912        }
10913
10914        // Wait for the provider to be published...
10915        synchronized (cpr) {
10916            while (cpr.provider == null) {
10917                if (cpr.launchingApp == null) {
10918                    Slog.w(TAG, "Unable to launch app "
10919                            + cpi.applicationInfo.packageName + "/"
10920                            + cpi.applicationInfo.uid + " for provider "
10921                            + name + ": launching app became null");
10922                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10923                            UserHandle.getUserId(cpi.applicationInfo.uid),
10924                            cpi.applicationInfo.packageName,
10925                            cpi.applicationInfo.uid, name);
10926                    return null;
10927                }
10928                try {
10929                    if (DEBUG_MU) Slog.v(TAG_MU,
10930                            "Waiting to start provider " + cpr
10931                            + " launchingApp=" + cpr.launchingApp);
10932                    if (conn != null) {
10933                        conn.waiting = true;
10934                    }
10935                    cpr.wait();
10936                } catch (InterruptedException ex) {
10937                } finally {
10938                    if (conn != null) {
10939                        conn.waiting = false;
10940                    }
10941                }
10942            }
10943        }
10944        return cpr != null ? cpr.newHolder(conn) : null;
10945    }
10946
10947    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10948            ProcessRecord r, final int userId) {
10949        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10950                cpi.packageName, userId)) {
10951
10952            final boolean callerForeground = r == null || r.setSchedGroup
10953                    != ProcessList.SCHED_GROUP_BACKGROUND;
10954
10955            // Show a permission review UI only for starting from a foreground app
10956            if (!callerForeground) {
10957                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10958                        + cpi.packageName + " requires a permissions review");
10959                return false;
10960            }
10961
10962            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10963            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10964                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10965            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10966
10967            if (DEBUG_PERMISSIONS_REVIEW) {
10968                Slog.i(TAG, "u" + userId + " Launching permission review "
10969                        + "for package " + cpi.packageName);
10970            }
10971
10972            final UserHandle userHandle = new UserHandle(userId);
10973            mHandler.post(new Runnable() {
10974                @Override
10975                public void run() {
10976                    mContext.startActivityAsUser(intent, userHandle);
10977                }
10978            });
10979
10980            return false;
10981        }
10982
10983        return true;
10984    }
10985
10986    PackageManagerInternal getPackageManagerInternalLocked() {
10987        if (mPackageManagerInt == null) {
10988            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10989        }
10990        return mPackageManagerInt;
10991    }
10992
10993    @Override
10994    public final ContentProviderHolder getContentProvider(
10995            IApplicationThread caller, String name, int userId, boolean stable) {
10996        enforceNotIsolatedCaller("getContentProvider");
10997        if (caller == null) {
10998            String msg = "null IApplicationThread when getting content provider "
10999                    + name;
11000            Slog.w(TAG, msg);
11001            throw new SecurityException(msg);
11002        }
11003        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11004        // with cross-user grant.
11005        return getContentProviderImpl(caller, name, null, stable, userId);
11006    }
11007
11008    public ContentProviderHolder getContentProviderExternal(
11009            String name, int userId, IBinder token) {
11010        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11011            "Do not have permission in call getContentProviderExternal()");
11012        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11013                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11014        return getContentProviderExternalUnchecked(name, token, userId);
11015    }
11016
11017    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11018            IBinder token, int userId) {
11019        return getContentProviderImpl(null, name, token, true, userId);
11020    }
11021
11022    /**
11023     * Drop a content provider from a ProcessRecord's bookkeeping
11024     */
11025    public void removeContentProvider(IBinder connection, boolean stable) {
11026        enforceNotIsolatedCaller("removeContentProvider");
11027        long ident = Binder.clearCallingIdentity();
11028        try {
11029            synchronized (this) {
11030                ContentProviderConnection conn;
11031                try {
11032                    conn = (ContentProviderConnection)connection;
11033                } catch (ClassCastException e) {
11034                    String msg ="removeContentProvider: " + connection
11035                            + " not a ContentProviderConnection";
11036                    Slog.w(TAG, msg);
11037                    throw new IllegalArgumentException(msg);
11038                }
11039                if (conn == null) {
11040                    throw new NullPointerException("connection is null");
11041                }
11042                if (decProviderCountLocked(conn, null, null, stable)) {
11043                    updateOomAdjLocked();
11044                }
11045            }
11046        } finally {
11047            Binder.restoreCallingIdentity(ident);
11048        }
11049    }
11050
11051    public void removeContentProviderExternal(String name, IBinder token) {
11052        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11053            "Do not have permission in call removeContentProviderExternal()");
11054        int userId = UserHandle.getCallingUserId();
11055        long ident = Binder.clearCallingIdentity();
11056        try {
11057            removeContentProviderExternalUnchecked(name, token, userId);
11058        } finally {
11059            Binder.restoreCallingIdentity(ident);
11060        }
11061    }
11062
11063    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11064        synchronized (this) {
11065            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11066            if(cpr == null) {
11067                //remove from mProvidersByClass
11068                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11069                return;
11070            }
11071
11072            //update content provider record entry info
11073            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11074            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11075            if (localCpr.hasExternalProcessHandles()) {
11076                if (localCpr.removeExternalProcessHandleLocked(token)) {
11077                    updateOomAdjLocked();
11078                } else {
11079                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11080                            + " with no external reference for token: "
11081                            + token + ".");
11082                }
11083            } else {
11084                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11085                        + " with no external references.");
11086            }
11087        }
11088    }
11089
11090    public final void publishContentProviders(IApplicationThread caller,
11091            List<ContentProviderHolder> providers) {
11092        if (providers == null) {
11093            return;
11094        }
11095
11096        enforceNotIsolatedCaller("publishContentProviders");
11097        synchronized (this) {
11098            final ProcessRecord r = getRecordForAppLocked(caller);
11099            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11100            if (r == null) {
11101                throw new SecurityException(
11102                        "Unable to find app for caller " + caller
11103                      + " (pid=" + Binder.getCallingPid()
11104                      + ") when publishing content providers");
11105            }
11106
11107            final long origId = Binder.clearCallingIdentity();
11108
11109            final int N = providers.size();
11110            for (int i = 0; i < N; i++) {
11111                ContentProviderHolder src = providers.get(i);
11112                if (src == null || src.info == null || src.provider == null) {
11113                    continue;
11114                }
11115                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11116                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11117                if (dst != null) {
11118                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11119                    mProviderMap.putProviderByClass(comp, dst);
11120                    String names[] = dst.info.authority.split(";");
11121                    for (int j = 0; j < names.length; j++) {
11122                        mProviderMap.putProviderByName(names[j], dst);
11123                    }
11124
11125                    int launchingCount = mLaunchingProviders.size();
11126                    int j;
11127                    boolean wasInLaunchingProviders = false;
11128                    for (j = 0; j < launchingCount; j++) {
11129                        if (mLaunchingProviders.get(j) == dst) {
11130                            mLaunchingProviders.remove(j);
11131                            wasInLaunchingProviders = true;
11132                            j--;
11133                            launchingCount--;
11134                        }
11135                    }
11136                    if (wasInLaunchingProviders) {
11137                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11138                    }
11139                    synchronized (dst) {
11140                        dst.provider = src.provider;
11141                        dst.proc = r;
11142                        dst.notifyAll();
11143                    }
11144                    updateOomAdjLocked(r);
11145                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11146                            src.info.authority);
11147                }
11148            }
11149
11150            Binder.restoreCallingIdentity(origId);
11151        }
11152    }
11153
11154    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11155        ContentProviderConnection conn;
11156        try {
11157            conn = (ContentProviderConnection)connection;
11158        } catch (ClassCastException e) {
11159            String msg ="refContentProvider: " + connection
11160                    + " not a ContentProviderConnection";
11161            Slog.w(TAG, msg);
11162            throw new IllegalArgumentException(msg);
11163        }
11164        if (conn == null) {
11165            throw new NullPointerException("connection is null");
11166        }
11167
11168        synchronized (this) {
11169            if (stable > 0) {
11170                conn.numStableIncs += stable;
11171            }
11172            stable = conn.stableCount + stable;
11173            if (stable < 0) {
11174                throw new IllegalStateException("stableCount < 0: " + stable);
11175            }
11176
11177            if (unstable > 0) {
11178                conn.numUnstableIncs += unstable;
11179            }
11180            unstable = conn.unstableCount + unstable;
11181            if (unstable < 0) {
11182                throw new IllegalStateException("unstableCount < 0: " + unstable);
11183            }
11184
11185            if ((stable+unstable) <= 0) {
11186                throw new IllegalStateException("ref counts can't go to zero here: stable="
11187                        + stable + " unstable=" + unstable);
11188            }
11189            conn.stableCount = stable;
11190            conn.unstableCount = unstable;
11191            return !conn.dead;
11192        }
11193    }
11194
11195    public void unstableProviderDied(IBinder connection) {
11196        ContentProviderConnection conn;
11197        try {
11198            conn = (ContentProviderConnection)connection;
11199        } catch (ClassCastException e) {
11200            String msg ="refContentProvider: " + connection
11201                    + " not a ContentProviderConnection";
11202            Slog.w(TAG, msg);
11203            throw new IllegalArgumentException(msg);
11204        }
11205        if (conn == null) {
11206            throw new NullPointerException("connection is null");
11207        }
11208
11209        // Safely retrieve the content provider associated with the connection.
11210        IContentProvider provider;
11211        synchronized (this) {
11212            provider = conn.provider.provider;
11213        }
11214
11215        if (provider == null) {
11216            // Um, yeah, we're way ahead of you.
11217            return;
11218        }
11219
11220        // Make sure the caller is being honest with us.
11221        if (provider.asBinder().pingBinder()) {
11222            // Er, no, still looks good to us.
11223            synchronized (this) {
11224                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11225                        + " says " + conn + " died, but we don't agree");
11226                return;
11227            }
11228        }
11229
11230        // Well look at that!  It's dead!
11231        synchronized (this) {
11232            if (conn.provider.provider != provider) {
11233                // But something changed...  good enough.
11234                return;
11235            }
11236
11237            ProcessRecord proc = conn.provider.proc;
11238            if (proc == null || proc.thread == null) {
11239                // Seems like the process is already cleaned up.
11240                return;
11241            }
11242
11243            // As far as we're concerned, this is just like receiving a
11244            // death notification...  just a bit prematurely.
11245            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11246                    + ") early provider death");
11247            final long ident = Binder.clearCallingIdentity();
11248            try {
11249                appDiedLocked(proc);
11250            } finally {
11251                Binder.restoreCallingIdentity(ident);
11252            }
11253        }
11254    }
11255
11256    @Override
11257    public void appNotRespondingViaProvider(IBinder connection) {
11258        enforceCallingPermission(
11259                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11260
11261        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11262        if (conn == null) {
11263            Slog.w(TAG, "ContentProviderConnection is null");
11264            return;
11265        }
11266
11267        final ProcessRecord host = conn.provider.proc;
11268        if (host == null) {
11269            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11270            return;
11271        }
11272
11273        mHandler.post(new Runnable() {
11274            @Override
11275            public void run() {
11276                mAppErrors.appNotResponding(host, null, null, false,
11277                        "ContentProvider not responding");
11278            }
11279        });
11280    }
11281
11282    public final void installSystemProviders() {
11283        List<ProviderInfo> providers;
11284        synchronized (this) {
11285            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11286            providers = generateApplicationProvidersLocked(app);
11287            if (providers != null) {
11288                for (int i=providers.size()-1; i>=0; i--) {
11289                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11290                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11291                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11292                                + ": not system .apk");
11293                        providers.remove(i);
11294                    }
11295                }
11296            }
11297        }
11298        if (providers != null) {
11299            mSystemThread.installSystemProviders(providers);
11300        }
11301
11302        mCoreSettingsObserver = new CoreSettingsObserver(this);
11303        mFontScaleSettingObserver = new FontScaleSettingObserver();
11304
11305        //mUsageStatsService.monitorPackages();
11306    }
11307
11308    private void startPersistentApps(int matchFlags) {
11309        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11310
11311        synchronized (this) {
11312            try {
11313                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11314                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11315                for (ApplicationInfo app : apps) {
11316                    if (!"android".equals(app.packageName)) {
11317                        addAppLocked(app, false, null /* ABI override */);
11318                    }
11319                }
11320            } catch (RemoteException ex) {
11321            }
11322        }
11323    }
11324
11325    /**
11326     * When a user is unlocked, we need to install encryption-unaware providers
11327     * belonging to any running apps.
11328     */
11329    private void installEncryptionUnawareProviders(int userId) {
11330        // We're only interested in providers that are encryption unaware, and
11331        // we don't care about uninstalled apps, since there's no way they're
11332        // running at this point.
11333        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11334
11335        synchronized (this) {
11336            final int NP = mProcessNames.getMap().size();
11337            for (int ip = 0; ip < NP; ip++) {
11338                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11339                final int NA = apps.size();
11340                for (int ia = 0; ia < NA; ia++) {
11341                    final ProcessRecord app = apps.valueAt(ia);
11342                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11343
11344                    final int NG = app.pkgList.size();
11345                    for (int ig = 0; ig < NG; ig++) {
11346                        try {
11347                            final String pkgName = app.pkgList.keyAt(ig);
11348                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11349                                    .getPackageInfo(pkgName, matchFlags, userId);
11350                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11351                                for (ProviderInfo pi : pkgInfo.providers) {
11352                                    // TODO: keep in sync with generateApplicationProvidersLocked
11353                                    final boolean processMatch = Objects.equals(pi.processName,
11354                                            app.processName) || pi.multiprocess;
11355                                    final boolean userMatch = isSingleton(pi.processName,
11356                                            pi.applicationInfo, pi.name, pi.flags)
11357                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
11358                                    if (processMatch && userMatch) {
11359                                        Log.v(TAG, "Installing " + pi);
11360                                        app.thread.scheduleInstallProvider(pi);
11361                                    } else {
11362                                        Log.v(TAG, "Skipping " + pi);
11363                                    }
11364                                }
11365                            }
11366                        } catch (RemoteException ignored) {
11367                        }
11368                    }
11369                }
11370            }
11371        }
11372    }
11373
11374    /**
11375     * Allows apps to retrieve the MIME type of a URI.
11376     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11377     * users, then it does not need permission to access the ContentProvider.
11378     * Either, it needs cross-user uri grants.
11379     *
11380     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11381     *
11382     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11383     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11384     */
11385    public String getProviderMimeType(Uri uri, int userId) {
11386        enforceNotIsolatedCaller("getProviderMimeType");
11387        final String name = uri.getAuthority();
11388        int callingUid = Binder.getCallingUid();
11389        int callingPid = Binder.getCallingPid();
11390        long ident = 0;
11391        boolean clearedIdentity = false;
11392        synchronized (this) {
11393            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11394        }
11395        if (canClearIdentity(callingPid, callingUid, userId)) {
11396            clearedIdentity = true;
11397            ident = Binder.clearCallingIdentity();
11398        }
11399        ContentProviderHolder holder = null;
11400        try {
11401            holder = getContentProviderExternalUnchecked(name, null, userId);
11402            if (holder != null) {
11403                return holder.provider.getType(uri);
11404            }
11405        } catch (RemoteException e) {
11406            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11407            return null;
11408        } catch (Exception e) {
11409            Log.w(TAG, "Exception while determining type of " + uri, e);
11410            return null;
11411        } finally {
11412            // We need to clear the identity to call removeContentProviderExternalUnchecked
11413            if (!clearedIdentity) {
11414                ident = Binder.clearCallingIdentity();
11415            }
11416            try {
11417                if (holder != null) {
11418                    removeContentProviderExternalUnchecked(name, null, userId);
11419                }
11420            } finally {
11421                Binder.restoreCallingIdentity(ident);
11422            }
11423        }
11424
11425        return null;
11426    }
11427
11428    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11429        if (UserHandle.getUserId(callingUid) == userId) {
11430            return true;
11431        }
11432        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11433                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11434                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11435                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11436                return true;
11437        }
11438        return false;
11439    }
11440
11441    // =========================================================
11442    // GLOBAL MANAGEMENT
11443    // =========================================================
11444
11445    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11446            boolean isolated, int isolatedUid) {
11447        String proc = customProcess != null ? customProcess : info.processName;
11448        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11449        final int userId = UserHandle.getUserId(info.uid);
11450        int uid = info.uid;
11451        if (isolated) {
11452            if (isolatedUid == 0) {
11453                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11454                while (true) {
11455                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11456                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11457                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11458                    }
11459                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11460                    mNextIsolatedProcessUid++;
11461                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11462                        // No process for this uid, use it.
11463                        break;
11464                    }
11465                    stepsLeft--;
11466                    if (stepsLeft <= 0) {
11467                        return null;
11468                    }
11469                }
11470            } else {
11471                // Special case for startIsolatedProcess (internal only), where
11472                // the uid of the isolated process is specified by the caller.
11473                uid = isolatedUid;
11474            }
11475
11476            // Register the isolated UID with this application so BatteryStats knows to
11477            // attribute resource usage to the application.
11478            //
11479            // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
11480            // about the process state of the isolated UID *before* it is registered with the
11481            // owning application.
11482            mBatteryStatsService.addIsolatedUid(uid, info.uid);
11483        }
11484        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11485        if (!mBooted && !mBooting
11486                && userId == UserHandle.USER_SYSTEM
11487                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11488            r.persistent = true;
11489            r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11490        }
11491        addProcessNameLocked(r);
11492        return r;
11493    }
11494
11495    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11496            String abiOverride) {
11497        ProcessRecord app;
11498        if (!isolated) {
11499            app = getProcessRecordLocked(info.processName, info.uid, true);
11500        } else {
11501            app = null;
11502        }
11503
11504        if (app == null) {
11505            app = newProcessRecordLocked(info, null, isolated, 0);
11506            updateLruProcessLocked(app, false, null);
11507            updateOomAdjLocked();
11508        }
11509
11510        // This package really, really can not be stopped.
11511        try {
11512            AppGlobals.getPackageManager().setPackageStoppedState(
11513                    info.packageName, false, UserHandle.getUserId(app.uid));
11514        } catch (RemoteException e) {
11515        } catch (IllegalArgumentException e) {
11516            Slog.w(TAG, "Failed trying to unstop package "
11517                    + info.packageName + ": " + e);
11518        }
11519
11520        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11521            app.persistent = true;
11522            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11523        }
11524        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11525            mPersistentStartingProcesses.add(app);
11526            startProcessLocked(app, "added application", app.processName, abiOverride,
11527                    null /* entryPoint */, null /* entryPointArgs */);
11528        }
11529
11530        return app;
11531    }
11532
11533    public void unhandledBack() {
11534        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11535                "unhandledBack()");
11536
11537        synchronized(this) {
11538            final long origId = Binder.clearCallingIdentity();
11539            try {
11540                getFocusedStack().unhandledBackLocked();
11541            } finally {
11542                Binder.restoreCallingIdentity(origId);
11543            }
11544        }
11545    }
11546
11547    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11548        enforceNotIsolatedCaller("openContentUri");
11549        final int userId = UserHandle.getCallingUserId();
11550        String name = uri.getAuthority();
11551        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11552        ParcelFileDescriptor pfd = null;
11553        if (cph != null) {
11554            // We record the binder invoker's uid in thread-local storage before
11555            // going to the content provider to open the file.  Later, in the code
11556            // that handles all permissions checks, we look for this uid and use
11557            // that rather than the Activity Manager's own uid.  The effect is that
11558            // we do the check against the caller's permissions even though it looks
11559            // to the content provider like the Activity Manager itself is making
11560            // the request.
11561            Binder token = new Binder();
11562            sCallerIdentity.set(new Identity(
11563                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11564            try {
11565                pfd = cph.provider.openFile(null, uri, "r", null, token);
11566            } catch (FileNotFoundException e) {
11567                // do nothing; pfd will be returned null
11568            } finally {
11569                // Ensure that whatever happens, we clean up the identity state
11570                sCallerIdentity.remove();
11571                // Ensure we're done with the provider.
11572                removeContentProviderExternalUnchecked(name, null, userId);
11573            }
11574        } else {
11575            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11576        }
11577        return pfd;
11578    }
11579
11580    // Actually is sleeping or shutting down or whatever else in the future
11581    // is an inactive state.
11582    boolean isSleepingOrShuttingDownLocked() {
11583        return isSleepingLocked() || mShuttingDown;
11584    }
11585
11586    boolean isShuttingDownLocked() {
11587        return mShuttingDown;
11588    }
11589
11590    boolean isSleepingLocked() {
11591        return mSleeping;
11592    }
11593
11594    void onWakefulnessChanged(int wakefulness) {
11595        synchronized(this) {
11596            mWakefulness = wakefulness;
11597            updateSleepIfNeededLocked();
11598        }
11599    }
11600
11601    void finishRunningVoiceLocked() {
11602        if (mRunningVoice != null) {
11603            mRunningVoice = null;
11604            mVoiceWakeLock.release();
11605            updateSleepIfNeededLocked();
11606        }
11607    }
11608
11609    void startTimeTrackingFocusedActivityLocked() {
11610        final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
11611        if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
11612            mCurAppTimeTracker.start(resumedActivity.packageName);
11613        }
11614    }
11615
11616    void updateSleepIfNeededLocked() {
11617        if (mSleeping && !shouldSleepLocked()) {
11618            mSleeping = false;
11619            startTimeTrackingFocusedActivityLocked();
11620            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11621            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11622            updateOomAdjLocked();
11623        } else if (!mSleeping && shouldSleepLocked()) {
11624            mSleeping = true;
11625            if (mCurAppTimeTracker != null) {
11626                mCurAppTimeTracker.stop();
11627            }
11628            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11629            mStackSupervisor.goingToSleepLocked();
11630            updateOomAdjLocked();
11631
11632            // Initialize the wake times of all processes.
11633            checkExcessivePowerUsageLocked(false);
11634            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11635            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11636            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11637        }
11638    }
11639
11640    private boolean shouldSleepLocked() {
11641        // Resume applications while running a voice interactor.
11642        if (mRunningVoice != null) {
11643            return false;
11644        }
11645
11646        // TODO: Transform the lock screen state into a sleep token instead.
11647        switch (mWakefulness) {
11648            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11649            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11650            case PowerManagerInternal.WAKEFULNESS_DOZING:
11651                // Pause applications whenever the lock screen is shown or any sleep
11652                // tokens have been acquired.
11653                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11654            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11655            default:
11656                // If we're asleep then pause applications unconditionally.
11657                return true;
11658        }
11659    }
11660
11661    /** Pokes the task persister. */
11662    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11663        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11664    }
11665
11666    /** Notifies all listeners when the task stack has changed. */
11667    void notifyTaskStackChangedLocked() {
11668        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11669        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11670        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11671        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11672    }
11673
11674    /** Notifies all listeners when an Activity is pinned. */
11675    void notifyActivityPinnedLocked() {
11676        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11677        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11678    }
11679
11680    /**
11681     * Notifies all listeners when an attempt was made to start an an activity that is already
11682     * running in the pinned stack and the activity was not actually started, but the task is
11683     * either brought to the front or a new Intent is delivered to it.
11684     */
11685    void notifyPinnedActivityRestartAttemptLocked() {
11686        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11687        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11688    }
11689
11690    /** Notifies all listeners when the pinned stack animation ends. */
11691    @Override
11692    public void notifyPinnedStackAnimationEnded() {
11693        synchronized (this) {
11694            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11695            mHandler.obtainMessage(
11696                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11697        }
11698    }
11699
11700    @Override
11701    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11702        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11703    }
11704
11705    @Override
11706    public boolean shutdown(int timeout) {
11707        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11708                != PackageManager.PERMISSION_GRANTED) {
11709            throw new SecurityException("Requires permission "
11710                    + android.Manifest.permission.SHUTDOWN);
11711        }
11712
11713        boolean timedout = false;
11714
11715        synchronized(this) {
11716            mShuttingDown = true;
11717            updateEventDispatchingLocked();
11718            timedout = mStackSupervisor.shutdownLocked(timeout);
11719        }
11720
11721        mAppOpsService.shutdown();
11722        if (mUsageStatsService != null) {
11723            mUsageStatsService.prepareShutdown();
11724        }
11725        mBatteryStatsService.shutdown();
11726        synchronized (this) {
11727            mProcessStats.shutdownLocked();
11728            notifyTaskPersisterLocked(null, true);
11729        }
11730
11731        return timedout;
11732    }
11733
11734    public final void activitySlept(IBinder token) {
11735        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11736
11737        final long origId = Binder.clearCallingIdentity();
11738
11739        synchronized (this) {
11740            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11741            if (r != null) {
11742                mStackSupervisor.activitySleptLocked(r);
11743            }
11744        }
11745
11746        Binder.restoreCallingIdentity(origId);
11747    }
11748
11749    private String lockScreenShownToString() {
11750        switch (mLockScreenShown) {
11751            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11752            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11753            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11754            default: return "Unknown=" + mLockScreenShown;
11755        }
11756    }
11757
11758    void logLockScreen(String msg) {
11759        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11760                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11761                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11762                + " mSleeping=" + mSleeping);
11763    }
11764
11765    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11766        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11767        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11768        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11769            boolean wasRunningVoice = mRunningVoice != null;
11770            mRunningVoice = session;
11771            if (!wasRunningVoice) {
11772                mVoiceWakeLock.acquire();
11773                updateSleepIfNeededLocked();
11774            }
11775        }
11776    }
11777
11778    private void updateEventDispatchingLocked() {
11779        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11780    }
11781
11782    public void setLockScreenShown(boolean showing, boolean occluded) {
11783        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11784                != PackageManager.PERMISSION_GRANTED) {
11785            throw new SecurityException("Requires permission "
11786                    + android.Manifest.permission.DEVICE_POWER);
11787        }
11788
11789        synchronized(this) {
11790            long ident = Binder.clearCallingIdentity();
11791            try {
11792                if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11793                mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11794                if (showing && occluded) {
11795                    // The lock screen is currently showing, but is occluded by a window that can
11796                    // show on top of the lock screen. In this can we want to dismiss the docked
11797                    // stack since it will be complicated/risky to try to put the activity on top
11798                    // of the lock screen in the right fullscreen configuration.
11799                    mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11800                            mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11801                }
11802
11803                updateSleepIfNeededLocked();
11804            } finally {
11805                Binder.restoreCallingIdentity(ident);
11806            }
11807        }
11808    }
11809
11810    @Override
11811    public void notifyLockedProfile(@UserIdInt int userId) {
11812        try {
11813            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11814                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11815            }
11816        } catch (RemoteException ex) {
11817            throw new SecurityException("Fail to check is caller a privileged app", ex);
11818        }
11819
11820        synchronized (this) {
11821            if (mStackSupervisor.isUserLockedProfile(userId)) {
11822                final long ident = Binder.clearCallingIdentity();
11823                try {
11824                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11825                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11826                        // If there is no device lock, we will show the profile's credential page.
11827                        mActivityStarter.showConfirmDeviceCredential(userId);
11828                    } else {
11829                        // Showing launcher to avoid user entering credential twice.
11830                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11831                    }
11832                } finally {
11833                    Binder.restoreCallingIdentity(ident);
11834                }
11835            }
11836        }
11837    }
11838
11839    @Override
11840    public void startConfirmDeviceCredentialIntent(Intent intent) {
11841        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11842        synchronized (this) {
11843            final long ident = Binder.clearCallingIdentity();
11844            try {
11845                mActivityStarter.startConfirmCredentialIntent(intent);
11846            } finally {
11847                Binder.restoreCallingIdentity(ident);
11848            }
11849        }
11850    }
11851
11852    @Override
11853    public void stopAppSwitches() {
11854        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11855                != PackageManager.PERMISSION_GRANTED) {
11856            throw new SecurityException("viewquires permission "
11857                    + android.Manifest.permission.STOP_APP_SWITCHES);
11858        }
11859
11860        synchronized(this) {
11861            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11862                    + APP_SWITCH_DELAY_TIME;
11863            mDidAppSwitch = false;
11864            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11865            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11866            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11867        }
11868    }
11869
11870    public void resumeAppSwitches() {
11871        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11872                != PackageManager.PERMISSION_GRANTED) {
11873            throw new SecurityException("Requires permission "
11874                    + android.Manifest.permission.STOP_APP_SWITCHES);
11875        }
11876
11877        synchronized(this) {
11878            // Note that we don't execute any pending app switches... we will
11879            // let those wait until either the timeout, or the next start
11880            // activity request.
11881            mAppSwitchesAllowedTime = 0;
11882        }
11883    }
11884
11885    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11886            int callingPid, int callingUid, String name) {
11887        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11888            return true;
11889        }
11890
11891        int perm = checkComponentPermission(
11892                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11893                sourceUid, -1, true);
11894        if (perm == PackageManager.PERMISSION_GRANTED) {
11895            return true;
11896        }
11897
11898        // If the actual IPC caller is different from the logical source, then
11899        // also see if they are allowed to control app switches.
11900        if (callingUid != -1 && callingUid != sourceUid) {
11901            perm = checkComponentPermission(
11902                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11903                    callingUid, -1, true);
11904            if (perm == PackageManager.PERMISSION_GRANTED) {
11905                return true;
11906            }
11907        }
11908
11909        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11910        return false;
11911    }
11912
11913    public void setDebugApp(String packageName, boolean waitForDebugger,
11914            boolean persistent) {
11915        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11916                "setDebugApp()");
11917
11918        long ident = Binder.clearCallingIdentity();
11919        try {
11920            // Note that this is not really thread safe if there are multiple
11921            // callers into it at the same time, but that's not a situation we
11922            // care about.
11923            if (persistent) {
11924                final ContentResolver resolver = mContext.getContentResolver();
11925                Settings.Global.putString(
11926                    resolver, Settings.Global.DEBUG_APP,
11927                    packageName);
11928                Settings.Global.putInt(
11929                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11930                    waitForDebugger ? 1 : 0);
11931            }
11932
11933            synchronized (this) {
11934                if (!persistent) {
11935                    mOrigDebugApp = mDebugApp;
11936                    mOrigWaitForDebugger = mWaitForDebugger;
11937                }
11938                mDebugApp = packageName;
11939                mWaitForDebugger = waitForDebugger;
11940                mDebugTransient = !persistent;
11941                if (packageName != null) {
11942                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11943                            false, UserHandle.USER_ALL, "set debug app");
11944                }
11945            }
11946        } finally {
11947            Binder.restoreCallingIdentity(ident);
11948        }
11949    }
11950
11951    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11952        synchronized (this) {
11953            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11954            if (!isDebuggable) {
11955                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11956                    throw new SecurityException("Process not debuggable: " + app.packageName);
11957                }
11958            }
11959
11960            mTrackAllocationApp = processName;
11961        }
11962    }
11963
11964    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11965        synchronized (this) {
11966            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11967            if (!isDebuggable) {
11968                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11969                    throw new SecurityException("Process not debuggable: " + app.packageName);
11970                }
11971            }
11972            mProfileApp = processName;
11973            mProfileFile = profilerInfo.profileFile;
11974            if (mProfileFd != null) {
11975                try {
11976                    mProfileFd.close();
11977                } catch (IOException e) {
11978                }
11979                mProfileFd = null;
11980            }
11981            mProfileFd = profilerInfo.profileFd;
11982            mSamplingInterval = profilerInfo.samplingInterval;
11983            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11984            mProfileType = 0;
11985        }
11986    }
11987
11988    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11989        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11990        if (!isDebuggable) {
11991            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11992                throw new SecurityException("Process not debuggable: " + app.packageName);
11993            }
11994        }
11995        mNativeDebuggingApp = processName;
11996    }
11997
11998    @Override
11999    public void setAlwaysFinish(boolean enabled) {
12000        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12001                "setAlwaysFinish()");
12002
12003        long ident = Binder.clearCallingIdentity();
12004        try {
12005            Settings.Global.putInt(
12006                    mContext.getContentResolver(),
12007                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12008
12009            synchronized (this) {
12010                mAlwaysFinishActivities = enabled;
12011            }
12012        } finally {
12013            Binder.restoreCallingIdentity(ident);
12014        }
12015    }
12016
12017    @Override
12018    public void setLenientBackgroundCheck(boolean enabled) {
12019        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
12020                "setLenientBackgroundCheck()");
12021
12022        long ident = Binder.clearCallingIdentity();
12023        try {
12024            Settings.Global.putInt(
12025                    mContext.getContentResolver(),
12026                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
12027
12028            synchronized (this) {
12029                mLenientBackgroundCheck = enabled;
12030            }
12031        } finally {
12032            Binder.restoreCallingIdentity(ident);
12033        }
12034    }
12035
12036    @Override
12037    public void setActivityController(IActivityController controller, boolean imAMonkey) {
12038        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12039                "setActivityController()");
12040        synchronized (this) {
12041            mController = controller;
12042            mControllerIsAMonkey = imAMonkey;
12043            Watchdog.getInstance().setActivityController(controller);
12044        }
12045    }
12046
12047    @Override
12048    public void setUserIsMonkey(boolean userIsMonkey) {
12049        synchronized (this) {
12050            synchronized (mPidsSelfLocked) {
12051                final int callingPid = Binder.getCallingPid();
12052                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
12053                if (precessRecord == null) {
12054                    throw new SecurityException("Unknown process: " + callingPid);
12055                }
12056                if (precessRecord.instrumentationUiAutomationConnection  == null) {
12057                    throw new SecurityException("Only an instrumentation process "
12058                            + "with a UiAutomation can call setUserIsMonkey");
12059                }
12060            }
12061            mUserIsMonkey = userIsMonkey;
12062        }
12063    }
12064
12065    @Override
12066    public boolean isUserAMonkey() {
12067        synchronized (this) {
12068            // If there is a controller also implies the user is a monkey.
12069            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12070        }
12071    }
12072
12073    public void requestBugReport(int bugreportType) {
12074        String extraOptions = null;
12075        switch (bugreportType) {
12076            case ActivityManager.BUGREPORT_OPTION_FULL:
12077                // Default options.
12078                break;
12079            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12080                extraOptions = "bugreportplus";
12081                break;
12082            case ActivityManager.BUGREPORT_OPTION_REMOTE:
12083                extraOptions = "bugreportremote";
12084                break;
12085            case ActivityManager.BUGREPORT_OPTION_WEAR:
12086                extraOptions = "bugreportwear";
12087                break;
12088            default:
12089                throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12090                        + bugreportType);
12091        }
12092        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12093        if (extraOptions != null) {
12094            SystemProperties.set("dumpstate.options", extraOptions);
12095        }
12096        SystemProperties.set("ctl.start", "bugreport");
12097    }
12098
12099    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12100        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12101    }
12102
12103    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12104        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
12105            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12106        }
12107        return KEY_DISPATCHING_TIMEOUT;
12108    }
12109
12110    @Override
12111    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12112        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12113                != PackageManager.PERMISSION_GRANTED) {
12114            throw new SecurityException("Requires permission "
12115                    + android.Manifest.permission.FILTER_EVENTS);
12116        }
12117        ProcessRecord proc;
12118        long timeout;
12119        synchronized (this) {
12120            synchronized (mPidsSelfLocked) {
12121                proc = mPidsSelfLocked.get(pid);
12122            }
12123            timeout = getInputDispatchingTimeoutLocked(proc);
12124        }
12125
12126        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12127            return -1;
12128        }
12129
12130        return timeout;
12131    }
12132
12133    /**
12134     * Handle input dispatching timeouts.
12135     * Returns whether input dispatching should be aborted or not.
12136     */
12137    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12138            final ActivityRecord activity, final ActivityRecord parent,
12139            final boolean aboveSystem, String reason) {
12140        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12141                != PackageManager.PERMISSION_GRANTED) {
12142            throw new SecurityException("Requires permission "
12143                    + android.Manifest.permission.FILTER_EVENTS);
12144        }
12145
12146        final String annotation;
12147        if (reason == null) {
12148            annotation = "Input dispatching timed out";
12149        } else {
12150            annotation = "Input dispatching timed out (" + reason + ")";
12151        }
12152
12153        if (proc != null) {
12154            synchronized (this) {
12155                if (proc.debugging) {
12156                    return false;
12157                }
12158
12159                if (mDidDexOpt) {
12160                    // Give more time since we were dexopting.
12161                    mDidDexOpt = false;
12162                    return false;
12163                }
12164
12165                if (proc.instrumentationClass != null) {
12166                    Bundle info = new Bundle();
12167                    info.putString("shortMsg", "keyDispatchingTimedOut");
12168                    info.putString("longMsg", annotation);
12169                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12170                    return true;
12171                }
12172            }
12173            mHandler.post(new Runnable() {
12174                @Override
12175                public void run() {
12176                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12177                }
12178            });
12179        }
12180
12181        return true;
12182    }
12183
12184    @Override
12185    public Bundle getAssistContextExtras(int requestType) {
12186        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12187                null, null, true /* focused */, true /* newSessionId */,
12188                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12189        if (pae == null) {
12190            return null;
12191        }
12192        synchronized (pae) {
12193            while (!pae.haveResult) {
12194                try {
12195                    pae.wait();
12196                } catch (InterruptedException e) {
12197                }
12198            }
12199        }
12200        synchronized (this) {
12201            buildAssistBundleLocked(pae, pae.result);
12202            mPendingAssistExtras.remove(pae);
12203            mUiHandler.removeCallbacks(pae);
12204        }
12205        return pae.extras;
12206    }
12207
12208    @Override
12209    public boolean isAssistDataAllowedOnCurrentActivity() {
12210        int userId;
12211        synchronized (this) {
12212            userId = mUserController.getCurrentUserIdLocked();
12213            ActivityRecord activity = getFocusedStack().topActivity();
12214            if (activity == null) {
12215                return false;
12216            }
12217            userId = activity.userId;
12218        }
12219        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12220                Context.DEVICE_POLICY_SERVICE);
12221        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12222    }
12223
12224    @Override
12225    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12226        long ident = Binder.clearCallingIdentity();
12227        try {
12228            synchronized (this) {
12229                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12230                ActivityRecord top = getFocusedStack().topActivity();
12231                if (top != caller) {
12232                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12233                            + " is not current top " + top);
12234                    return false;
12235                }
12236                if (!top.nowVisible) {
12237                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12238                            + " is not visible");
12239                    return false;
12240                }
12241            }
12242            AssistUtils utils = new AssistUtils(mContext);
12243            return utils.showSessionForActiveService(args,
12244                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12245        } finally {
12246            Binder.restoreCallingIdentity(ident);
12247        }
12248    }
12249
12250    @Override
12251    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12252            Bundle receiverExtras,
12253            IBinder activityToken, boolean focused, boolean newSessionId) {
12254        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12255                activityToken, focused, newSessionId,
12256                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12257                != null;
12258    }
12259
12260    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12261            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12262            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12263        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12264                "enqueueAssistContext()");
12265        synchronized (this) {
12266            ActivityRecord activity = getFocusedStack().topActivity();
12267            if (activity == null) {
12268                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12269                return null;
12270            }
12271            if (activity.app == null || activity.app.thread == null) {
12272                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12273                return null;
12274            }
12275            if (focused) {
12276                if (activityToken != null) {
12277                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12278                    if (activity != caller) {
12279                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12280                                + " is not current top " + activity);
12281                        return null;
12282                    }
12283                }
12284            } else {
12285                activity = ActivityRecord.forTokenLocked(activityToken);
12286                if (activity == null) {
12287                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12288                            + " couldn't be found");
12289                    return null;
12290                }
12291            }
12292
12293            PendingAssistExtras pae;
12294            Bundle extras = new Bundle();
12295            if (args != null) {
12296                extras.putAll(args);
12297            }
12298            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12299            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12300            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12301                    userHandle);
12302            // Increment the sessionId if necessary
12303            if (newSessionId) {
12304                mViSessionId++;
12305            }
12306            try {
12307                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12308                        requestType, mViSessionId);
12309                mPendingAssistExtras.add(pae);
12310                mUiHandler.postDelayed(pae, timeout);
12311            } catch (RemoteException e) {
12312                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12313                return null;
12314            }
12315            return pae;
12316        }
12317    }
12318
12319    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12320        IResultReceiver receiver;
12321        synchronized (this) {
12322            mPendingAssistExtras.remove(pae);
12323            receiver = pae.receiver;
12324        }
12325        if (receiver != null) {
12326            // Caller wants result sent back to them.
12327            Bundle sendBundle = new Bundle();
12328            // At least return the receiver extras
12329            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12330                    pae.receiverExtras);
12331            try {
12332                pae.receiver.send(0, sendBundle);
12333            } catch (RemoteException e) {
12334            }
12335        }
12336    }
12337
12338    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12339        if (result != null) {
12340            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12341        }
12342        if (pae.hint != null) {
12343            pae.extras.putBoolean(pae.hint, true);
12344        }
12345    }
12346
12347    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12348            AssistContent content, Uri referrer) {
12349        PendingAssistExtras pae = (PendingAssistExtras)token;
12350        synchronized (pae) {
12351            pae.result = extras;
12352            pae.structure = structure;
12353            pae.content = content;
12354            if (referrer != null) {
12355                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12356            }
12357            pae.haveResult = true;
12358            pae.notifyAll();
12359            if (pae.intent == null && pae.receiver == null) {
12360                // Caller is just waiting for the result.
12361                return;
12362            }
12363        }
12364
12365        // We are now ready to launch the assist activity.
12366        IResultReceiver sendReceiver = null;
12367        Bundle sendBundle = null;
12368        synchronized (this) {
12369            buildAssistBundleLocked(pae, extras);
12370            boolean exists = mPendingAssistExtras.remove(pae);
12371            mUiHandler.removeCallbacks(pae);
12372            if (!exists) {
12373                // Timed out.
12374                return;
12375            }
12376            if ((sendReceiver=pae.receiver) != null) {
12377                // Caller wants result sent back to them.
12378                sendBundle = new Bundle();
12379                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12380                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12381                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12382                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12383                        pae.receiverExtras);
12384            }
12385        }
12386        if (sendReceiver != null) {
12387            try {
12388                sendReceiver.send(0, sendBundle);
12389            } catch (RemoteException e) {
12390            }
12391            return;
12392        }
12393
12394        long ident = Binder.clearCallingIdentity();
12395        try {
12396            pae.intent.replaceExtras(pae.extras);
12397            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12398                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12399                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12400            closeSystemDialogs("assist");
12401            try {
12402                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12403            } catch (ActivityNotFoundException e) {
12404                Slog.w(TAG, "No activity to handle assist action.", e);
12405            }
12406        } finally {
12407            Binder.restoreCallingIdentity(ident);
12408        }
12409    }
12410
12411    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12412            Bundle args) {
12413        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12414                true /* focused */, true /* newSessionId */,
12415                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12416    }
12417
12418    public void registerProcessObserver(IProcessObserver observer) {
12419        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12420                "registerProcessObserver()");
12421        synchronized (this) {
12422            mProcessObservers.register(observer);
12423        }
12424    }
12425
12426    @Override
12427    public void unregisterProcessObserver(IProcessObserver observer) {
12428        synchronized (this) {
12429            mProcessObservers.unregister(observer);
12430        }
12431    }
12432
12433    @Override
12434    public void registerUidObserver(IUidObserver observer, int which) {
12435        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12436                "registerUidObserver()");
12437        synchronized (this) {
12438            mUidObservers.register(observer, which);
12439        }
12440    }
12441
12442    @Override
12443    public void unregisterUidObserver(IUidObserver observer) {
12444        synchronized (this) {
12445            mUidObservers.unregister(observer);
12446        }
12447    }
12448
12449    @Override
12450    public boolean convertFromTranslucent(IBinder token) {
12451        final long origId = Binder.clearCallingIdentity();
12452        try {
12453            synchronized (this) {
12454                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12455                if (r == null) {
12456                    return false;
12457                }
12458                final boolean translucentChanged = r.changeWindowTranslucency(true);
12459                if (translucentChanged) {
12460                    r.getStack().releaseBackgroundResources(r);
12461                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12462                }
12463                mWindowManager.setAppFullscreen(token, true);
12464                return translucentChanged;
12465            }
12466        } finally {
12467            Binder.restoreCallingIdentity(origId);
12468        }
12469    }
12470
12471    @Override
12472    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12473        final long origId = Binder.clearCallingIdentity();
12474        try {
12475            synchronized (this) {
12476                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12477                if (r == null) {
12478                    return false;
12479                }
12480                int index = r.task.mActivities.lastIndexOf(r);
12481                if (index > 0) {
12482                    ActivityRecord under = r.task.mActivities.get(index - 1);
12483                    under.returningOptions = options;
12484                }
12485                final boolean translucentChanged = r.changeWindowTranslucency(false);
12486                if (translucentChanged) {
12487                    r.getStack().convertActivityToTranslucent(r);
12488                }
12489                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12490                mWindowManager.setAppFullscreen(token, false);
12491                return translucentChanged;
12492            }
12493        } finally {
12494            Binder.restoreCallingIdentity(origId);
12495        }
12496    }
12497
12498    @Override
12499    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12500        final long origId = Binder.clearCallingIdentity();
12501        try {
12502            synchronized (this) {
12503                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12504                if (r != null) {
12505                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12506                }
12507            }
12508            return false;
12509        } finally {
12510            Binder.restoreCallingIdentity(origId);
12511        }
12512    }
12513
12514    @Override
12515    public boolean isBackgroundVisibleBehind(IBinder token) {
12516        final long origId = Binder.clearCallingIdentity();
12517        try {
12518            synchronized (this) {
12519                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12520                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12521                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12522                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12523                return visible;
12524            }
12525        } finally {
12526            Binder.restoreCallingIdentity(origId);
12527        }
12528    }
12529
12530    @Override
12531    public ActivityOptions getActivityOptions(IBinder token) {
12532        final long origId = Binder.clearCallingIdentity();
12533        try {
12534            synchronized (this) {
12535                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12536                if (r != null) {
12537                    final ActivityOptions activityOptions = r.pendingOptions;
12538                    r.pendingOptions = null;
12539                    return activityOptions;
12540                }
12541                return null;
12542            }
12543        } finally {
12544            Binder.restoreCallingIdentity(origId);
12545        }
12546    }
12547
12548    @Override
12549    public void setImmersive(IBinder token, boolean immersive) {
12550        synchronized(this) {
12551            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12552            if (r == null) {
12553                throw new IllegalArgumentException();
12554            }
12555            r.immersive = immersive;
12556
12557            // update associated state if we're frontmost
12558            if (r == mStackSupervisor.getResumedActivityLocked()) {
12559                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12560                applyUpdateLockStateLocked(r);
12561            }
12562        }
12563    }
12564
12565    @Override
12566    public boolean isImmersive(IBinder token) {
12567        synchronized (this) {
12568            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12569            if (r == null) {
12570                throw new IllegalArgumentException();
12571            }
12572            return r.immersive;
12573        }
12574    }
12575
12576    public void setVrThread(int tid) {
12577        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12578            throw new UnsupportedOperationException("VR mode not supported on this device!");
12579        }
12580
12581        synchronized (this) {
12582            ProcessRecord proc;
12583            synchronized (mPidsSelfLocked) {
12584                final int pid = Binder.getCallingPid();
12585                proc = mPidsSelfLocked.get(pid);
12586
12587                if (proc != null && mInVrMode && tid >= 0) {
12588                    // ensure the tid belongs to the process
12589                    if (!Process.isThreadInProcess(pid, tid)) {
12590                        throw new IllegalArgumentException("VR thread does not belong to process");
12591                    }
12592
12593                    // reset existing VR thread to CFS if this thread still exists and belongs to
12594                    // the calling process
12595                    if (proc.vrThreadTid != 0
12596                            && Process.isThreadInProcess(pid, proc.vrThreadTid)) {
12597                        try {
12598                            Process.setThreadScheduler(proc.vrThreadTid, Process.SCHED_OTHER, 0);
12599                        } catch (IllegalArgumentException e) {
12600                            // Ignore this.  Only occurs in race condition where previous VR thread
12601                            // was destroyed during this method call.
12602                        }
12603                    }
12604
12605                    proc.vrThreadTid = tid;
12606
12607                    // promote to FIFO now if the tid is non-zero
12608                    try {
12609                        if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
12610                            proc.vrThreadTid > 0) {
12611                            Process.setThreadScheduler(proc.vrThreadTid,
12612                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12613                        }
12614                    } catch (IllegalArgumentException e) {
12615                        Slog.e(TAG, "Failed to set scheduling policy, thread does"
12616                               + " not exist:\n" + e);
12617                    }
12618                }
12619            }
12620        }
12621    }
12622
12623    @Override
12624    public void setRenderThread(int tid) {
12625        synchronized (this) {
12626            ProcessRecord proc;
12627            synchronized (mPidsSelfLocked) {
12628                int pid = Binder.getCallingPid();
12629                proc = mPidsSelfLocked.get(pid);
12630                if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
12631                    // ensure the tid belongs to the process
12632                    if (!Process.isThreadInProcess(pid, tid)) {
12633                        throw new IllegalArgumentException(
12634                            "Render thread does not belong to process");
12635                    }
12636                    proc.renderThreadTid = tid;
12637                    if (DEBUG_OOM_ADJ) {
12638                        Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
12639                    }
12640                    // promote to FIFO now
12641                    if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
12642                        if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
12643                        if (mUseFifoUiScheduling) {
12644                            Process.setThreadScheduler(proc.renderThreadTid,
12645                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12646                        } else {
12647                            Process.setThreadPriority(proc.renderThreadTid, -10);
12648                        }
12649                    }
12650                } else {
12651                    if (DEBUG_OOM_ADJ) {
12652                        Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
12653                               "PID: " + pid + ", TID: " + tid + " FIFO: " +
12654                               mUseFifoUiScheduling);
12655                    }
12656                }
12657            }
12658        }
12659    }
12660
12661    @Override
12662    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12663        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12664            throw new UnsupportedOperationException("VR mode not supported on this device!");
12665        }
12666
12667        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12668
12669        ActivityRecord r;
12670        synchronized (this) {
12671            r = ActivityRecord.isInStackLocked(token);
12672        }
12673
12674        if (r == null) {
12675            throw new IllegalArgumentException();
12676        }
12677
12678        int err;
12679        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12680                VrManagerInternal.NO_ERROR) {
12681            return err;
12682        }
12683
12684        synchronized(this) {
12685            r.requestedVrComponent = (enabled) ? packageName : null;
12686
12687            // Update associated state if this activity is currently focused
12688            if (r == mStackSupervisor.getResumedActivityLocked()) {
12689                applyUpdateVrModeLocked(r);
12690            }
12691            return 0;
12692        }
12693    }
12694
12695    @Override
12696    public boolean isVrModePackageEnabled(ComponentName packageName) {
12697        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12698            throw new UnsupportedOperationException("VR mode not supported on this device!");
12699        }
12700
12701        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12702
12703        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12704                VrManagerInternal.NO_ERROR;
12705    }
12706
12707    public boolean isTopActivityImmersive() {
12708        enforceNotIsolatedCaller("startActivity");
12709        synchronized (this) {
12710            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12711            return (r != null) ? r.immersive : false;
12712        }
12713    }
12714
12715    @Override
12716    public boolean isTopOfTask(IBinder token) {
12717        synchronized (this) {
12718            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12719            if (r == null) {
12720                throw new IllegalArgumentException();
12721            }
12722            return r.task.getTopActivity() == r;
12723        }
12724    }
12725
12726    @Override
12727    public void setHasTopUi(boolean hasTopUi) throws RemoteException {
12728        if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
12729            String msg = "Permission Denial: setHasTopUi() from pid="
12730                    + Binder.getCallingPid()
12731                    + ", uid=" + Binder.getCallingUid()
12732                    + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
12733            Slog.w(TAG, msg);
12734            throw new SecurityException(msg);
12735        }
12736        final int pid = Binder.getCallingPid();
12737        final long origId = Binder.clearCallingIdentity();
12738        try {
12739            synchronized (this) {
12740                boolean changed = false;
12741                ProcessRecord pr;
12742                synchronized (mPidsSelfLocked) {
12743                    pr = mPidsSelfLocked.get(pid);
12744                    if (pr == null) {
12745                        Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
12746                        return;
12747                    }
12748                    if (pr.hasTopUi != hasTopUi) {
12749                        Slog.i(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
12750                        pr.hasTopUi = hasTopUi;
12751                        changed = true;
12752                    }
12753                }
12754                if (changed) {
12755                    updateOomAdjLocked(pr);
12756                }
12757            }
12758        } finally {
12759            Binder.restoreCallingIdentity(origId);
12760        }
12761    }
12762
12763    public final void enterSafeMode() {
12764        synchronized(this) {
12765            // It only makes sense to do this before the system is ready
12766            // and started launching other packages.
12767            if (!mSystemReady) {
12768                try {
12769                    AppGlobals.getPackageManager().enterSafeMode();
12770                } catch (RemoteException e) {
12771                }
12772            }
12773
12774            mSafeMode = true;
12775        }
12776    }
12777
12778    public final void showSafeModeOverlay() {
12779        View v = LayoutInflater.from(mContext).inflate(
12780                com.android.internal.R.layout.safe_mode, null);
12781        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12782        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12783        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12784        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12785        lp.gravity = Gravity.BOTTOM | Gravity.START;
12786        lp.format = v.getBackground().getOpacity();
12787        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12788                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12789        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12790        ((WindowManager)mContext.getSystemService(
12791                Context.WINDOW_SERVICE)).addView(v, lp);
12792    }
12793
12794    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12795        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12796            return;
12797        }
12798        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12799        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12800        synchronized (stats) {
12801            if (mBatteryStatsService.isOnBattery()) {
12802                mBatteryStatsService.enforceCallingPermission();
12803                int MY_UID = Binder.getCallingUid();
12804                final int uid;
12805                if (sender == null) {
12806                    uid = sourceUid;
12807                } else {
12808                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12809                }
12810                BatteryStatsImpl.Uid.Pkg pkg =
12811                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12812                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12813                pkg.noteWakeupAlarmLocked(tag);
12814            }
12815        }
12816    }
12817
12818    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12819        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12820            return;
12821        }
12822        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12823        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12824        synchronized (stats) {
12825            mBatteryStatsService.enforceCallingPermission();
12826            int MY_UID = Binder.getCallingUid();
12827            final int uid;
12828            if (sender == null) {
12829                uid = sourceUid;
12830            } else {
12831                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12832            }
12833            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12834        }
12835    }
12836
12837    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12838        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12839            return;
12840        }
12841        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12842        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12843        synchronized (stats) {
12844            mBatteryStatsService.enforceCallingPermission();
12845            int MY_UID = Binder.getCallingUid();
12846            final int uid;
12847            if (sender == null) {
12848                uid = sourceUid;
12849            } else {
12850                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12851            }
12852            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12853        }
12854    }
12855
12856    public boolean killPids(int[] pids, String pReason, boolean secure) {
12857        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12858            throw new SecurityException("killPids only available to the system");
12859        }
12860        String reason = (pReason == null) ? "Unknown" : pReason;
12861        // XXX Note: don't acquire main activity lock here, because the window
12862        // manager calls in with its locks held.
12863
12864        boolean killed = false;
12865        synchronized (mPidsSelfLocked) {
12866            int worstType = 0;
12867            for (int i=0; i<pids.length; i++) {
12868                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12869                if (proc != null) {
12870                    int type = proc.setAdj;
12871                    if (type > worstType) {
12872                        worstType = type;
12873                    }
12874                }
12875            }
12876
12877            // If the worst oom_adj is somewhere in the cached proc LRU range,
12878            // then constrain it so we will kill all cached procs.
12879            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12880                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12881                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12882            }
12883
12884            // If this is not a secure call, don't let it kill processes that
12885            // are important.
12886            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12887                worstType = ProcessList.SERVICE_ADJ;
12888            }
12889
12890            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12891            for (int i=0; i<pids.length; i++) {
12892                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12893                if (proc == null) {
12894                    continue;
12895                }
12896                int adj = proc.setAdj;
12897                if (adj >= worstType && !proc.killedByAm) {
12898                    proc.kill(reason, true);
12899                    killed = true;
12900                }
12901            }
12902        }
12903        return killed;
12904    }
12905
12906    @Override
12907    public void killUid(int appId, int userId, String reason) {
12908        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12909        synchronized (this) {
12910            final long identity = Binder.clearCallingIdentity();
12911            try {
12912                killPackageProcessesLocked(null, appId, userId,
12913                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12914                        reason != null ? reason : "kill uid");
12915            } finally {
12916                Binder.restoreCallingIdentity(identity);
12917            }
12918        }
12919    }
12920
12921    @Override
12922    public boolean killProcessesBelowForeground(String reason) {
12923        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12924            throw new SecurityException("killProcessesBelowForeground() only available to system");
12925        }
12926
12927        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12928    }
12929
12930    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12931        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12932            throw new SecurityException("killProcessesBelowAdj() only available to system");
12933        }
12934
12935        boolean killed = false;
12936        synchronized (mPidsSelfLocked) {
12937            final int size = mPidsSelfLocked.size();
12938            for (int i = 0; i < size; i++) {
12939                final int pid = mPidsSelfLocked.keyAt(i);
12940                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12941                if (proc == null) continue;
12942
12943                final int adj = proc.setAdj;
12944                if (adj > belowAdj && !proc.killedByAm) {
12945                    proc.kill(reason, true);
12946                    killed = true;
12947                }
12948            }
12949        }
12950        return killed;
12951    }
12952
12953    @Override
12954    public void hang(final IBinder who, boolean allowRestart) {
12955        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12956                != PackageManager.PERMISSION_GRANTED) {
12957            throw new SecurityException("Requires permission "
12958                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12959        }
12960
12961        final IBinder.DeathRecipient death = new DeathRecipient() {
12962            @Override
12963            public void binderDied() {
12964                synchronized (this) {
12965                    notifyAll();
12966                }
12967            }
12968        };
12969
12970        try {
12971            who.linkToDeath(death, 0);
12972        } catch (RemoteException e) {
12973            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12974            return;
12975        }
12976
12977        synchronized (this) {
12978            Watchdog.getInstance().setAllowRestart(allowRestart);
12979            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12980            synchronized (death) {
12981                while (who.isBinderAlive()) {
12982                    try {
12983                        death.wait();
12984                    } catch (InterruptedException e) {
12985                    }
12986                }
12987            }
12988            Watchdog.getInstance().setAllowRestart(true);
12989        }
12990    }
12991
12992    @Override
12993    public void restart() {
12994        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12995                != PackageManager.PERMISSION_GRANTED) {
12996            throw new SecurityException("Requires permission "
12997                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12998        }
12999
13000        Log.i(TAG, "Sending shutdown broadcast...");
13001
13002        BroadcastReceiver br = new BroadcastReceiver() {
13003            @Override public void onReceive(Context context, Intent intent) {
13004                // Now the broadcast is done, finish up the low-level shutdown.
13005                Log.i(TAG, "Shutting down activity manager...");
13006                shutdown(10000);
13007                Log.i(TAG, "Shutdown complete, restarting!");
13008                Process.killProcess(Process.myPid());
13009                System.exit(10);
13010            }
13011        };
13012
13013        // First send the high-level shut down broadcast.
13014        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13015        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13016        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13017        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13018        mContext.sendOrderedBroadcastAsUser(intent,
13019                UserHandle.ALL, null, br, mHandler, 0, null, null);
13020        */
13021        br.onReceive(mContext, intent);
13022    }
13023
13024    private long getLowRamTimeSinceIdle(long now) {
13025        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13026    }
13027
13028    @Override
13029    public void performIdleMaintenance() {
13030        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13031                != PackageManager.PERMISSION_GRANTED) {
13032            throw new SecurityException("Requires permission "
13033                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13034        }
13035
13036        synchronized (this) {
13037            final long now = SystemClock.uptimeMillis();
13038            final long timeSinceLastIdle = now - mLastIdleTime;
13039            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13040            mLastIdleTime = now;
13041            mLowRamTimeSinceLastIdle = 0;
13042            if (mLowRamStartTime != 0) {
13043                mLowRamStartTime = now;
13044            }
13045
13046            StringBuilder sb = new StringBuilder(128);
13047            sb.append("Idle maintenance over ");
13048            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13049            sb.append(" low RAM for ");
13050            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13051            Slog.i(TAG, sb.toString());
13052
13053            // If at least 1/3 of our time since the last idle period has been spent
13054            // with RAM low, then we want to kill processes.
13055            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
13056
13057            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13058                ProcessRecord proc = mLruProcesses.get(i);
13059                if (proc.notCachedSinceIdle) {
13060                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
13061                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
13062                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
13063                        if (doKilling && proc.initialIdlePss != 0
13064                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
13065                            sb = new StringBuilder(128);
13066                            sb.append("Kill");
13067                            sb.append(proc.processName);
13068                            sb.append(" in idle maint: pss=");
13069                            sb.append(proc.lastPss);
13070                            sb.append(", swapPss=");
13071                            sb.append(proc.lastSwapPss);
13072                            sb.append(", initialPss=");
13073                            sb.append(proc.initialIdlePss);
13074                            sb.append(", period=");
13075                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13076                            sb.append(", lowRamPeriod=");
13077                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13078                            Slog.wtfQuiet(TAG, sb.toString());
13079                            proc.kill("idle maint (pss " + proc.lastPss
13080                                    + " from " + proc.initialIdlePss + ")", true);
13081                        }
13082                    }
13083                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
13084                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
13085                    proc.notCachedSinceIdle = true;
13086                    proc.initialIdlePss = 0;
13087                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
13088                            mTestPssMode, isSleepingLocked(), now);
13089                }
13090            }
13091
13092            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
13093            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
13094        }
13095    }
13096
13097    @Override
13098    public void sendIdleJobTrigger() {
13099        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13100                != PackageManager.PERMISSION_GRANTED) {
13101            throw new SecurityException("Requires permission "
13102                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13103        }
13104
13105        final long ident = Binder.clearCallingIdentity();
13106        try {
13107            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
13108                    .setPackage("android")
13109                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13110            broadcastIntent(null, intent, null, null, 0, null, null, null,
13111                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
13112        } finally {
13113            Binder.restoreCallingIdentity(ident);
13114        }
13115    }
13116
13117    private void retrieveSettings() {
13118        final ContentResolver resolver = mContext.getContentResolver();
13119        final boolean freeformWindowManagement =
13120                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
13121                        || Settings.Global.getInt(
13122                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
13123        final boolean supportsPictureInPicture =
13124                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
13125
13126        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
13127        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
13128        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
13129        final boolean alwaysFinishActivities =
13130                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
13131        final boolean lenientBackgroundCheck =
13132                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
13133        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
13134        final boolean forceResizable = Settings.Global.getInt(
13135                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
13136        final boolean supportsLeanbackOnly =
13137                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
13138
13139        // Transfer any global setting for forcing RTL layout, into a System Property
13140        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
13141
13142        final Configuration configuration = new Configuration();
13143        Settings.System.getConfiguration(resolver, configuration);
13144        if (forceRtl) {
13145            // This will take care of setting the correct layout direction flags
13146            configuration.setLayoutDirection(configuration.locale);
13147        }
13148
13149        synchronized (this) {
13150            mDebugApp = mOrigDebugApp = debugApp;
13151            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
13152            mAlwaysFinishActivities = alwaysFinishActivities;
13153            mLenientBackgroundCheck = lenientBackgroundCheck;
13154            mSupportsLeanbackOnly = supportsLeanbackOnly;
13155            mForceResizableActivities = forceResizable;
13156            mWindowManager.setForceResizableTasks(mForceResizableActivities);
13157            if (supportsMultiWindow || forceResizable) {
13158                mSupportsMultiWindow = true;
13159                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
13160                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
13161            } else {
13162                mSupportsMultiWindow = false;
13163                mSupportsFreeformWindowManagement = false;
13164                mSupportsPictureInPicture = false;
13165            }
13166            // This happens before any activities are started, so we can change global configuration
13167            // in-place.
13168            updateConfigurationLocked(configuration, null, true);
13169            final Configuration globalConfig = getGlobalConfiguration();
13170            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
13171
13172            // Load resources only after the current configuration has been set.
13173            final Resources res = mContext.getResources();
13174            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
13175            mThumbnailWidth = res.getDimensionPixelSize(
13176                    com.android.internal.R.dimen.thumbnail_width);
13177            mThumbnailHeight = res.getDimensionPixelSize(
13178                    com.android.internal.R.dimen.thumbnail_height);
13179            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
13180                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
13181            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
13182                    com.android.internal.R.string.config_appsNotReportingCrashes));
13183            mUserController.mUserSwitchUiEnabled = !res.getBoolean(
13184                    com.android.internal.R.bool.config_customUserSwitchUi);
13185            if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
13186                mFullscreenThumbnailScale = (float) res
13187                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
13188                    (float) globalConfig.screenWidthDp;
13189            } else {
13190                mFullscreenThumbnailScale = res.getFraction(
13191                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13192            }
13193        }
13194    }
13195
13196    public boolean testIsSystemReady() {
13197        // no need to synchronize(this) just to read & return the value
13198        return mSystemReady;
13199    }
13200
13201    public void systemReady(final Runnable goingCallback) {
13202        synchronized(this) {
13203            if (mSystemReady) {
13204                // If we're done calling all the receivers, run the next "boot phase" passed in
13205                // by the SystemServer
13206                if (goingCallback != null) {
13207                    goingCallback.run();
13208                }
13209                return;
13210            }
13211
13212            mLocalDeviceIdleController
13213                    = LocalServices.getService(DeviceIdleController.LocalService.class);
13214
13215            // Make sure we have the current profile info, since it is needed for security checks.
13216            mUserController.onSystemReady();
13217            mRecentTasks.onSystemReadyLocked();
13218            mAppOpsService.systemReady();
13219            mSystemReady = true;
13220        }
13221
13222        ArrayList<ProcessRecord> procsToKill = null;
13223        synchronized(mPidsSelfLocked) {
13224            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13225                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13226                if (!isAllowedWhileBooting(proc.info)){
13227                    if (procsToKill == null) {
13228                        procsToKill = new ArrayList<ProcessRecord>();
13229                    }
13230                    procsToKill.add(proc);
13231                }
13232            }
13233        }
13234
13235        synchronized(this) {
13236            if (procsToKill != null) {
13237                for (int i=procsToKill.size()-1; i>=0; i--) {
13238                    ProcessRecord proc = procsToKill.get(i);
13239                    Slog.i(TAG, "Removing system update proc: " + proc);
13240                    removeProcessLocked(proc, true, false, "system update done");
13241                }
13242            }
13243
13244            // Now that we have cleaned up any update processes, we
13245            // are ready to start launching real processes and know that
13246            // we won't trample on them any more.
13247            mProcessesReady = true;
13248        }
13249
13250        Slog.i(TAG, "System now ready");
13251        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13252            SystemClock.uptimeMillis());
13253
13254        synchronized(this) {
13255            // Make sure we have no pre-ready processes sitting around.
13256
13257            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13258                ResolveInfo ri = mContext.getPackageManager()
13259                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13260                                STOCK_PM_FLAGS);
13261                CharSequence errorMsg = null;
13262                if (ri != null) {
13263                    ActivityInfo ai = ri.activityInfo;
13264                    ApplicationInfo app = ai.applicationInfo;
13265                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13266                        mTopAction = Intent.ACTION_FACTORY_TEST;
13267                        mTopData = null;
13268                        mTopComponent = new ComponentName(app.packageName,
13269                                ai.name);
13270                    } else {
13271                        errorMsg = mContext.getResources().getText(
13272                                com.android.internal.R.string.factorytest_not_system);
13273                    }
13274                } else {
13275                    errorMsg = mContext.getResources().getText(
13276                            com.android.internal.R.string.factorytest_no_action);
13277                }
13278                if (errorMsg != null) {
13279                    mTopAction = null;
13280                    mTopData = null;
13281                    mTopComponent = null;
13282                    Message msg = Message.obtain();
13283                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13284                    msg.getData().putCharSequence("msg", errorMsg);
13285                    mUiHandler.sendMessage(msg);
13286                }
13287            }
13288        }
13289
13290        retrieveSettings();
13291        final int currentUserId;
13292        synchronized (this) {
13293            currentUserId = mUserController.getCurrentUserIdLocked();
13294            readGrantedUriPermissionsLocked();
13295        }
13296
13297        if (goingCallback != null) goingCallback.run();
13298
13299        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13300                Integer.toString(currentUserId), currentUserId);
13301        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13302                Integer.toString(currentUserId), currentUserId);
13303        mSystemServiceManager.startUser(currentUserId);
13304
13305        synchronized (this) {
13306            // Only start up encryption-aware persistent apps; once user is
13307            // unlocked we'll come back around and start unaware apps
13308            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13309
13310            // Start up initial activity.
13311            mBooting = true;
13312            // Enable home activity for system user, so that the system can always boot. We don't
13313            // do this when the system user is not setup since the setup wizard should be the one
13314            // to handle home activity in this case.
13315            if (UserManager.isSplitSystemUser() &&
13316                    Settings.Secure.getInt(mContext.getContentResolver(),
13317                         Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
13318                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13319                try {
13320                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13321                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13322                            UserHandle.USER_SYSTEM);
13323                } catch (RemoteException e) {
13324                    throw e.rethrowAsRuntimeException();
13325                }
13326            }
13327            startHomeActivityLocked(currentUserId, "systemReady");
13328
13329            try {
13330                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13331                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13332                            + " data partition or your device will be unstable.");
13333                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13334                }
13335            } catch (RemoteException e) {
13336            }
13337
13338            if (!Build.isBuildConsistent()) {
13339                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13340                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13341            }
13342
13343            long ident = Binder.clearCallingIdentity();
13344            try {
13345                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13346                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13347                        | Intent.FLAG_RECEIVER_FOREGROUND);
13348                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13349                broadcastIntentLocked(null, null, intent,
13350                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13351                        null, false, false, MY_PID, Process.SYSTEM_UID,
13352                        currentUserId);
13353                intent = new Intent(Intent.ACTION_USER_STARTING);
13354                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13355                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13356                broadcastIntentLocked(null, null, intent,
13357                        null, new IIntentReceiver.Stub() {
13358                            @Override
13359                            public void performReceive(Intent intent, int resultCode, String data,
13360                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13361                                    throws RemoteException {
13362                            }
13363                        }, 0, null, null,
13364                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13365                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13366            } catch (Throwable t) {
13367                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13368            } finally {
13369                Binder.restoreCallingIdentity(ident);
13370            }
13371            mStackSupervisor.resumeFocusedStackTopActivityLocked();
13372            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13373        }
13374    }
13375
13376    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13377        synchronized (this) {
13378            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13379        }
13380    }
13381
13382    void skipCurrentReceiverLocked(ProcessRecord app) {
13383        for (BroadcastQueue queue : mBroadcastQueues) {
13384            queue.skipCurrentReceiverLocked(app);
13385        }
13386    }
13387
13388    /**
13389     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13390     * The application process will exit immediately after this call returns.
13391     * @param app object of the crashing app, null for the system server
13392     * @param crashInfo describing the exception
13393     */
13394    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13395        ProcessRecord r = findAppProcess(app, "Crash");
13396        final String processName = app == null ? "system_server"
13397                : (r == null ? "unknown" : r.processName);
13398
13399        handleApplicationCrashInner("crash", r, processName, crashInfo);
13400    }
13401
13402    /* Native crash reporting uses this inner version because it needs to be somewhat
13403     * decoupled from the AM-managed cleanup lifecycle
13404     */
13405    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13406            ApplicationErrorReport.CrashInfo crashInfo) {
13407        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13408                UserHandle.getUserId(Binder.getCallingUid()), processName,
13409                r == null ? -1 : r.info.flags,
13410                crashInfo.exceptionClassName,
13411                crashInfo.exceptionMessage,
13412                crashInfo.throwFileName,
13413                crashInfo.throwLineNumber);
13414
13415        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13416
13417        mAppErrors.crashApplication(r, crashInfo);
13418    }
13419
13420    public void handleApplicationStrictModeViolation(
13421            IBinder app,
13422            int violationMask,
13423            StrictMode.ViolationInfo info) {
13424        ProcessRecord r = findAppProcess(app, "StrictMode");
13425        if (r == null) {
13426            return;
13427        }
13428
13429        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13430            Integer stackFingerprint = info.hashCode();
13431            boolean logIt = true;
13432            synchronized (mAlreadyLoggedViolatedStacks) {
13433                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13434                    logIt = false;
13435                    // TODO: sub-sample into EventLog for these, with
13436                    // the info.durationMillis?  Then we'd get
13437                    // the relative pain numbers, without logging all
13438                    // the stack traces repeatedly.  We'd want to do
13439                    // likewise in the client code, which also does
13440                    // dup suppression, before the Binder call.
13441                } else {
13442                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13443                        mAlreadyLoggedViolatedStacks.clear();
13444                    }
13445                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13446                }
13447            }
13448            if (logIt) {
13449                logStrictModeViolationToDropBox(r, info);
13450            }
13451        }
13452
13453        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13454            AppErrorResult result = new AppErrorResult();
13455            synchronized (this) {
13456                final long origId = Binder.clearCallingIdentity();
13457
13458                Message msg = Message.obtain();
13459                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13460                HashMap<String, Object> data = new HashMap<String, Object>();
13461                data.put("result", result);
13462                data.put("app", r);
13463                data.put("violationMask", violationMask);
13464                data.put("info", info);
13465                msg.obj = data;
13466                mUiHandler.sendMessage(msg);
13467
13468                Binder.restoreCallingIdentity(origId);
13469            }
13470            int res = result.get();
13471            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13472        }
13473    }
13474
13475    // Depending on the policy in effect, there could be a bunch of
13476    // these in quick succession so we try to batch these together to
13477    // minimize disk writes, number of dropbox entries, and maximize
13478    // compression, by having more fewer, larger records.
13479    private void logStrictModeViolationToDropBox(
13480            ProcessRecord process,
13481            StrictMode.ViolationInfo info) {
13482        if (info == null) {
13483            return;
13484        }
13485        final boolean isSystemApp = process == null ||
13486                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13487                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13488        final String processName = process == null ? "unknown" : process.processName;
13489        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13490        final DropBoxManager dbox = (DropBoxManager)
13491                mContext.getSystemService(Context.DROPBOX_SERVICE);
13492
13493        // Exit early if the dropbox isn't configured to accept this report type.
13494        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13495
13496        boolean bufferWasEmpty;
13497        boolean needsFlush;
13498        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13499        synchronized (sb) {
13500            bufferWasEmpty = sb.length() == 0;
13501            appendDropBoxProcessHeaders(process, processName, sb);
13502            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13503            sb.append("System-App: ").append(isSystemApp).append("\n");
13504            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13505            if (info.violationNumThisLoop != 0) {
13506                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13507            }
13508            if (info.numAnimationsRunning != 0) {
13509                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13510            }
13511            if (info.broadcastIntentAction != null) {
13512                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13513            }
13514            if (info.durationMillis != -1) {
13515                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13516            }
13517            if (info.numInstances != -1) {
13518                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13519            }
13520            if (info.tags != null) {
13521                for (String tag : info.tags) {
13522                    sb.append("Span-Tag: ").append(tag).append("\n");
13523                }
13524            }
13525            sb.append("\n");
13526            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13527                sb.append(info.crashInfo.stackTrace);
13528                sb.append("\n");
13529            }
13530            if (info.message != null) {
13531                sb.append(info.message);
13532                sb.append("\n");
13533            }
13534
13535            // Only buffer up to ~64k.  Various logging bits truncate
13536            // things at 128k.
13537            needsFlush = (sb.length() > 64 * 1024);
13538        }
13539
13540        // Flush immediately if the buffer's grown too large, or this
13541        // is a non-system app.  Non-system apps are isolated with a
13542        // different tag & policy and not batched.
13543        //
13544        // Batching is useful during internal testing with
13545        // StrictMode settings turned up high.  Without batching,
13546        // thousands of separate files could be created on boot.
13547        if (!isSystemApp || needsFlush) {
13548            new Thread("Error dump: " + dropboxTag) {
13549                @Override
13550                public void run() {
13551                    String report;
13552                    synchronized (sb) {
13553                        report = sb.toString();
13554                        sb.delete(0, sb.length());
13555                        sb.trimToSize();
13556                    }
13557                    if (report.length() != 0) {
13558                        dbox.addText(dropboxTag, report);
13559                    }
13560                }
13561            }.start();
13562            return;
13563        }
13564
13565        // System app batching:
13566        if (!bufferWasEmpty) {
13567            // An existing dropbox-writing thread is outstanding, so
13568            // we don't need to start it up.  The existing thread will
13569            // catch the buffer appends we just did.
13570            return;
13571        }
13572
13573        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13574        // (After this point, we shouldn't access AMS internal data structures.)
13575        new Thread("Error dump: " + dropboxTag) {
13576            @Override
13577            public void run() {
13578                // 5 second sleep to let stacks arrive and be batched together
13579                try {
13580                    Thread.sleep(5000);  // 5 seconds
13581                } catch (InterruptedException e) {}
13582
13583                String errorReport;
13584                synchronized (mStrictModeBuffer) {
13585                    errorReport = mStrictModeBuffer.toString();
13586                    if (errorReport.length() == 0) {
13587                        return;
13588                    }
13589                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13590                    mStrictModeBuffer.trimToSize();
13591                }
13592                dbox.addText(dropboxTag, errorReport);
13593            }
13594        }.start();
13595    }
13596
13597    /**
13598     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13599     * @param app object of the crashing app, null for the system server
13600     * @param tag reported by the caller
13601     * @param system whether this wtf is coming from the system
13602     * @param crashInfo describing the context of the error
13603     * @return true if the process should exit immediately (WTF is fatal)
13604     */
13605    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13606            final ApplicationErrorReport.CrashInfo crashInfo) {
13607        final int callingUid = Binder.getCallingUid();
13608        final int callingPid = Binder.getCallingPid();
13609
13610        if (system) {
13611            // If this is coming from the system, we could very well have low-level
13612            // system locks held, so we want to do this all asynchronously.  And we
13613            // never want this to become fatal, so there is that too.
13614            mHandler.post(new Runnable() {
13615                @Override public void run() {
13616                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13617                }
13618            });
13619            return false;
13620        }
13621
13622        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13623                crashInfo);
13624
13625        if (r != null && r.pid != Process.myPid() &&
13626                Settings.Global.getInt(mContext.getContentResolver(),
13627                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13628            mAppErrors.crashApplication(r, crashInfo);
13629            return true;
13630        } else {
13631            return false;
13632        }
13633    }
13634
13635    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13636            final ApplicationErrorReport.CrashInfo crashInfo) {
13637        final ProcessRecord r = findAppProcess(app, "WTF");
13638        final String processName = app == null ? "system_server"
13639                : (r == null ? "unknown" : r.processName);
13640
13641        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13642                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13643
13644        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13645
13646        return r;
13647    }
13648
13649    /**
13650     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13651     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13652     */
13653    private ProcessRecord findAppProcess(IBinder app, String reason) {
13654        if (app == null) {
13655            return null;
13656        }
13657
13658        synchronized (this) {
13659            final int NP = mProcessNames.getMap().size();
13660            for (int ip=0; ip<NP; ip++) {
13661                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13662                final int NA = apps.size();
13663                for (int ia=0; ia<NA; ia++) {
13664                    ProcessRecord p = apps.valueAt(ia);
13665                    if (p.thread != null && p.thread.asBinder() == app) {
13666                        return p;
13667                    }
13668                }
13669            }
13670
13671            Slog.w(TAG, "Can't find mystery application for " + reason
13672                    + " from pid=" + Binder.getCallingPid()
13673                    + " uid=" + Binder.getCallingUid() + ": " + app);
13674            return null;
13675        }
13676    }
13677
13678    /**
13679     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13680     * to append various headers to the dropbox log text.
13681     */
13682    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13683            StringBuilder sb) {
13684        // Watchdog thread ends up invoking this function (with
13685        // a null ProcessRecord) to add the stack file to dropbox.
13686        // Do not acquire a lock on this (am) in such cases, as it
13687        // could cause a potential deadlock, if and when watchdog
13688        // is invoked due to unavailability of lock on am and it
13689        // would prevent watchdog from killing system_server.
13690        if (process == null) {
13691            sb.append("Process: ").append(processName).append("\n");
13692            return;
13693        }
13694        // Note: ProcessRecord 'process' is guarded by the service
13695        // instance.  (notably process.pkgList, which could otherwise change
13696        // concurrently during execution of this method)
13697        synchronized (this) {
13698            sb.append("Process: ").append(processName).append("\n");
13699            int flags = process.info.flags;
13700            IPackageManager pm = AppGlobals.getPackageManager();
13701            sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
13702            for (int ip=0; ip<process.pkgList.size(); ip++) {
13703                String pkg = process.pkgList.keyAt(ip);
13704                sb.append("Package: ").append(pkg);
13705                try {
13706                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13707                    if (pi != null) {
13708                        sb.append(" v").append(pi.versionCode);
13709                        if (pi.versionName != null) {
13710                            sb.append(" (").append(pi.versionName).append(")");
13711                        }
13712                    }
13713                } catch (RemoteException e) {
13714                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13715                }
13716                sb.append("\n");
13717            }
13718        }
13719    }
13720
13721    private static String processClass(ProcessRecord process) {
13722        if (process == null || process.pid == MY_PID) {
13723            return "system_server";
13724        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13725            return "system_app";
13726        } else {
13727            return "data_app";
13728        }
13729    }
13730
13731    private volatile long mWtfClusterStart;
13732    private volatile int mWtfClusterCount;
13733
13734    /**
13735     * Write a description of an error (crash, WTF, ANR) to the drop box.
13736     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13737     * @param process which caused the error, null means the system server
13738     * @param activity which triggered the error, null if unknown
13739     * @param parent activity related to the error, null if unknown
13740     * @param subject line related to the error, null if absent
13741     * @param report in long form describing the error, null if absent
13742     * @param dataFile text file to include in the report, null if none
13743     * @param crashInfo giving an application stack trace, null if absent
13744     */
13745    public void addErrorToDropBox(String eventType,
13746            ProcessRecord process, String processName, ActivityRecord activity,
13747            ActivityRecord parent, String subject,
13748            final String report, final File dataFile,
13749            final ApplicationErrorReport.CrashInfo crashInfo) {
13750        // NOTE -- this must never acquire the ActivityManagerService lock,
13751        // otherwise the watchdog may be prevented from resetting the system.
13752
13753        // Bail early if not published yet
13754        if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
13755        final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
13756
13757        // Exit early if the dropbox isn't configured to accept this report type.
13758        final String dropboxTag = processClass(process) + "_" + eventType;
13759        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13760
13761        // Rate-limit how often we're willing to do the heavy lifting below to
13762        // collect and record logs; currently 5 logs per 10 second period.
13763        final long now = SystemClock.elapsedRealtime();
13764        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13765            mWtfClusterStart = now;
13766            mWtfClusterCount = 1;
13767        } else {
13768            if (mWtfClusterCount++ >= 5) return;
13769        }
13770
13771        final StringBuilder sb = new StringBuilder(1024);
13772        appendDropBoxProcessHeaders(process, processName, sb);
13773        if (process != null) {
13774            sb.append("Foreground: ")
13775                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13776                    .append("\n");
13777        }
13778        if (activity != null) {
13779            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13780        }
13781        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13782            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13783        }
13784        if (parent != null && parent != activity) {
13785            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13786        }
13787        if (subject != null) {
13788            sb.append("Subject: ").append(subject).append("\n");
13789        }
13790        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13791        if (Debug.isDebuggerConnected()) {
13792            sb.append("Debugger: Connected\n");
13793        }
13794        sb.append("\n");
13795
13796        // Do the rest in a worker thread to avoid blocking the caller on I/O
13797        // (After this point, we shouldn't access AMS internal data structures.)
13798        Thread worker = new Thread("Error dump: " + dropboxTag) {
13799            @Override
13800            public void run() {
13801                if (report != null) {
13802                    sb.append(report);
13803                }
13804
13805                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13806                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13807                int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
13808                        - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
13809
13810                if (dataFile != null && maxDataFileSize > 0) {
13811                    try {
13812                        sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
13813                                    "\n\n[[TRUNCATED]]"));
13814                    } catch (IOException e) {
13815                        Slog.e(TAG, "Error reading " + dataFile, e);
13816                    }
13817                }
13818                if (crashInfo != null && crashInfo.stackTrace != null) {
13819                    sb.append(crashInfo.stackTrace);
13820                }
13821
13822                if (lines > 0) {
13823                    sb.append("\n");
13824
13825                    // Merge several logcat streams, and take the last N lines
13826                    InputStreamReader input = null;
13827                    try {
13828                        java.lang.Process logcat = new ProcessBuilder(
13829                                "/system/bin/timeout", "-k", "15s", "10s",
13830                                "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
13831                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13832                                        .redirectErrorStream(true).start();
13833
13834                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13835                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13836                        input = new InputStreamReader(logcat.getInputStream());
13837
13838                        int num;
13839                        char[] buf = new char[8192];
13840                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13841                    } catch (IOException e) {
13842                        Slog.e(TAG, "Error running logcat", e);
13843                    } finally {
13844                        if (input != null) try { input.close(); } catch (IOException e) {}
13845                    }
13846                }
13847
13848                dbox.addText(dropboxTag, sb.toString());
13849            }
13850        };
13851
13852        if (process == null) {
13853            // If process is null, we are being called from some internal code
13854            // and may be about to die -- run this synchronously.
13855            worker.run();
13856        } else {
13857            worker.start();
13858        }
13859    }
13860
13861    @Override
13862    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13863        enforceNotIsolatedCaller("getProcessesInErrorState");
13864        // assume our apps are happy - lazy create the list
13865        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13866
13867        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13868                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13869        int userId = UserHandle.getUserId(Binder.getCallingUid());
13870
13871        synchronized (this) {
13872
13873            // iterate across all processes
13874            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13875                ProcessRecord app = mLruProcesses.get(i);
13876                if (!allUsers && app.userId != userId) {
13877                    continue;
13878                }
13879                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13880                    // This one's in trouble, so we'll generate a report for it
13881                    // crashes are higher priority (in case there's a crash *and* an anr)
13882                    ActivityManager.ProcessErrorStateInfo report = null;
13883                    if (app.crashing) {
13884                        report = app.crashingReport;
13885                    } else if (app.notResponding) {
13886                        report = app.notRespondingReport;
13887                    }
13888
13889                    if (report != null) {
13890                        if (errList == null) {
13891                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13892                        }
13893                        errList.add(report);
13894                    } else {
13895                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13896                                " crashing = " + app.crashing +
13897                                " notResponding = " + app.notResponding);
13898                    }
13899                }
13900            }
13901        }
13902
13903        return errList;
13904    }
13905
13906    static int procStateToImportance(int procState, int memAdj,
13907            ActivityManager.RunningAppProcessInfo currApp) {
13908        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13909        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13910            currApp.lru = memAdj;
13911        } else {
13912            currApp.lru = 0;
13913        }
13914        return imp;
13915    }
13916
13917    private void fillInProcMemInfo(ProcessRecord app,
13918            ActivityManager.RunningAppProcessInfo outInfo) {
13919        outInfo.pid = app.pid;
13920        outInfo.uid = app.info.uid;
13921        if (mHeavyWeightProcess == app) {
13922            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13923        }
13924        if (app.persistent) {
13925            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13926        }
13927        if (app.activities.size() > 0) {
13928            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13929        }
13930        outInfo.lastTrimLevel = app.trimMemoryLevel;
13931        int adj = app.curAdj;
13932        int procState = app.curProcState;
13933        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13934        outInfo.importanceReasonCode = app.adjTypeCode;
13935        outInfo.processState = app.curProcState;
13936    }
13937
13938    @Override
13939    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13940        enforceNotIsolatedCaller("getRunningAppProcesses");
13941
13942        final int callingUid = Binder.getCallingUid();
13943
13944        // Lazy instantiation of list
13945        List<ActivityManager.RunningAppProcessInfo> runList = null;
13946        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13947                callingUid) == PackageManager.PERMISSION_GRANTED;
13948        final int userId = UserHandle.getUserId(callingUid);
13949        final boolean allUids = isGetTasksAllowed(
13950                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13951
13952        synchronized (this) {
13953            // Iterate across all processes
13954            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13955                ProcessRecord app = mLruProcesses.get(i);
13956                if ((!allUsers && app.userId != userId)
13957                        || (!allUids && app.uid != callingUid)) {
13958                    continue;
13959                }
13960                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13961                    // Generate process state info for running application
13962                    ActivityManager.RunningAppProcessInfo currApp =
13963                        new ActivityManager.RunningAppProcessInfo(app.processName,
13964                                app.pid, app.getPackageList());
13965                    fillInProcMemInfo(app, currApp);
13966                    if (app.adjSource instanceof ProcessRecord) {
13967                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13968                        currApp.importanceReasonImportance =
13969                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13970                                        app.adjSourceProcState);
13971                    } else if (app.adjSource instanceof ActivityRecord) {
13972                        ActivityRecord r = (ActivityRecord)app.adjSource;
13973                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13974                    }
13975                    if (app.adjTarget instanceof ComponentName) {
13976                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13977                    }
13978                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13979                    //        + " lru=" + currApp.lru);
13980                    if (runList == null) {
13981                        runList = new ArrayList<>();
13982                    }
13983                    runList.add(currApp);
13984                }
13985            }
13986        }
13987        return runList;
13988    }
13989
13990    @Override
13991    public List<ApplicationInfo> getRunningExternalApplications() {
13992        enforceNotIsolatedCaller("getRunningExternalApplications");
13993        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13994        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13995        if (runningApps != null && runningApps.size() > 0) {
13996            Set<String> extList = new HashSet<String>();
13997            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13998                if (app.pkgList != null) {
13999                    for (String pkg : app.pkgList) {
14000                        extList.add(pkg);
14001                    }
14002                }
14003            }
14004            IPackageManager pm = AppGlobals.getPackageManager();
14005            for (String pkg : extList) {
14006                try {
14007                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14008                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14009                        retList.add(info);
14010                    }
14011                } catch (RemoteException e) {
14012                }
14013            }
14014        }
14015        return retList;
14016    }
14017
14018    @Override
14019    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
14020        enforceNotIsolatedCaller("getMyMemoryState");
14021        synchronized (this) {
14022            ProcessRecord proc;
14023            synchronized (mPidsSelfLocked) {
14024                proc = mPidsSelfLocked.get(Binder.getCallingPid());
14025            }
14026            fillInProcMemInfo(proc, outInfo);
14027        }
14028    }
14029
14030    @Override
14031    public int getMemoryTrimLevel() {
14032        enforceNotIsolatedCaller("getMyMemoryState");
14033        synchronized (this) {
14034            return mLastMemoryLevel;
14035        }
14036    }
14037
14038    @Override
14039    public void onShellCommand(FileDescriptor in, FileDescriptor out,
14040            FileDescriptor err, String[] args, ShellCallback callback,
14041            ResultReceiver resultReceiver) {
14042        (new ActivityManagerShellCommand(this, false)).exec(
14043                this, in, out, err, args, callback, resultReceiver);
14044    }
14045
14046    @Override
14047    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
14048        if (checkCallingPermission(android.Manifest.permission.DUMP)
14049                != PackageManager.PERMISSION_GRANTED) {
14050            pw.println("Permission Denial: can't dump ActivityManager from from pid="
14051                    + Binder.getCallingPid()
14052                    + ", uid=" + Binder.getCallingUid()
14053                    + " without permission "
14054                    + android.Manifest.permission.DUMP);
14055            return;
14056        }
14057
14058        boolean dumpAll = false;
14059        boolean dumpClient = false;
14060        boolean dumpCheckin = false;
14061        boolean dumpCheckinFormat = false;
14062        boolean dumpVisibleStacks = false;
14063        String dumpPackage = null;
14064
14065        int opti = 0;
14066        while (opti < args.length) {
14067            String opt = args[opti];
14068            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14069                break;
14070            }
14071            opti++;
14072            if ("-a".equals(opt)) {
14073                dumpAll = true;
14074            } else if ("-c".equals(opt)) {
14075                dumpClient = true;
14076            } else if ("-v".equals(opt)) {
14077                dumpVisibleStacks = true;
14078            } else if ("-p".equals(opt)) {
14079                if (opti < args.length) {
14080                    dumpPackage = args[opti];
14081                    opti++;
14082                } else {
14083                    pw.println("Error: -p option requires package argument");
14084                    return;
14085                }
14086                dumpClient = true;
14087            } else if ("--checkin".equals(opt)) {
14088                dumpCheckin = dumpCheckinFormat = true;
14089            } else if ("-C".equals(opt)) {
14090                dumpCheckinFormat = true;
14091            } else if ("-h".equals(opt)) {
14092                ActivityManagerShellCommand.dumpHelp(pw, true);
14093                return;
14094            } else {
14095                pw.println("Unknown argument: " + opt + "; use -h for help");
14096            }
14097        }
14098
14099        long origId = Binder.clearCallingIdentity();
14100        boolean more = false;
14101        // Is the caller requesting to dump a particular piece of data?
14102        if (opti < args.length) {
14103            String cmd = args[opti];
14104            opti++;
14105            if ("activities".equals(cmd) || "a".equals(cmd)) {
14106                synchronized (this) {
14107                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14108                }
14109            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
14110                synchronized (this) {
14111                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
14112                }
14113            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
14114                String[] newArgs;
14115                String name;
14116                if (opti >= args.length) {
14117                    name = null;
14118                    newArgs = EMPTY_STRING_ARRAY;
14119                } else {
14120                    dumpPackage = args[opti];
14121                    opti++;
14122                    newArgs = new String[args.length - opti];
14123                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14124                            args.length - opti);
14125                }
14126                synchronized (this) {
14127                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
14128                }
14129            } else if ("broadcast-stats".equals(cmd)) {
14130                String[] newArgs;
14131                String name;
14132                if (opti >= args.length) {
14133                    name = null;
14134                    newArgs = EMPTY_STRING_ARRAY;
14135                } else {
14136                    dumpPackage = args[opti];
14137                    opti++;
14138                    newArgs = new String[args.length - opti];
14139                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14140                            args.length - opti);
14141                }
14142                synchronized (this) {
14143                    if (dumpCheckinFormat) {
14144                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
14145                                dumpPackage);
14146                    } else {
14147                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
14148                    }
14149                }
14150            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
14151                String[] newArgs;
14152                String name;
14153                if (opti >= args.length) {
14154                    name = null;
14155                    newArgs = EMPTY_STRING_ARRAY;
14156                } else {
14157                    dumpPackage = args[opti];
14158                    opti++;
14159                    newArgs = new String[args.length - opti];
14160                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14161                            args.length - opti);
14162                }
14163                synchronized (this) {
14164                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
14165                }
14166            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
14167                String[] newArgs;
14168                String name;
14169                if (opti >= args.length) {
14170                    name = null;
14171                    newArgs = EMPTY_STRING_ARRAY;
14172                } else {
14173                    dumpPackage = args[opti];
14174                    opti++;
14175                    newArgs = new String[args.length - opti];
14176                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14177                            args.length - opti);
14178                }
14179                synchronized (this) {
14180                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
14181                }
14182            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
14183                synchronized (this) {
14184                    dumpOomLocked(fd, pw, args, opti, true);
14185                }
14186            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
14187                synchronized (this) {
14188                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
14189                }
14190            } else if ("provider".equals(cmd)) {
14191                String[] newArgs;
14192                String name;
14193                if (opti >= args.length) {
14194                    name = null;
14195                    newArgs = EMPTY_STRING_ARRAY;
14196                } else {
14197                    name = args[opti];
14198                    opti++;
14199                    newArgs = new String[args.length - opti];
14200                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14201                }
14202                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
14203                    pw.println("No providers match: " + name);
14204                    pw.println("Use -h for help.");
14205                }
14206            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
14207                synchronized (this) {
14208                    dumpProvidersLocked(fd, pw, args, opti, true, null);
14209                }
14210            } else if ("service".equals(cmd)) {
14211                String[] newArgs;
14212                String name;
14213                if (opti >= args.length) {
14214                    name = null;
14215                    newArgs = EMPTY_STRING_ARRAY;
14216                } else {
14217                    name = args[opti];
14218                    opti++;
14219                    newArgs = new String[args.length - opti];
14220                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14221                            args.length - opti);
14222                }
14223                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14224                    pw.println("No services match: " + name);
14225                    pw.println("Use -h for help.");
14226                }
14227            } else if ("package".equals(cmd)) {
14228                String[] newArgs;
14229                if (opti >= args.length) {
14230                    pw.println("package: no package name specified");
14231                    pw.println("Use -h for help.");
14232                } else {
14233                    dumpPackage = args[opti];
14234                    opti++;
14235                    newArgs = new String[args.length - opti];
14236                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14237                            args.length - opti);
14238                    args = newArgs;
14239                    opti = 0;
14240                    more = true;
14241                }
14242            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14243                synchronized (this) {
14244                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14245                }
14246            } else if ("services".equals(cmd) || "s".equals(cmd)) {
14247                if (dumpClient) {
14248                    ActiveServices.ServiceDumper dumper;
14249                    synchronized (this) {
14250                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14251                                dumpPackage);
14252                    }
14253                    dumper.dumpWithClient();
14254                } else {
14255                    synchronized (this) {
14256                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14257                                dumpPackage).dumpLocked();
14258                    }
14259                }
14260            } else if ("locks".equals(cmd)) {
14261                LockGuard.dump(fd, pw, args);
14262            } else {
14263                // Dumping a single activity?
14264                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacks)) {
14265                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14266                    int res = shell.exec(this, null, fd, null, args, null,
14267                            new ResultReceiver(null));
14268                    if (res < 0) {
14269                        pw.println("Bad activity command, or no activities match: " + cmd);
14270                        pw.println("Use -h for help.");
14271                    }
14272                }
14273            }
14274            if (!more) {
14275                Binder.restoreCallingIdentity(origId);
14276                return;
14277            }
14278        }
14279
14280        // No piece of data specified, dump everything.
14281        if (dumpCheckinFormat) {
14282            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14283        } else if (dumpClient) {
14284            ActiveServices.ServiceDumper sdumper;
14285            synchronized (this) {
14286                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14287                pw.println();
14288                if (dumpAll) {
14289                    pw.println("-------------------------------------------------------------------------------");
14290                }
14291                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14292                pw.println();
14293                if (dumpAll) {
14294                    pw.println("-------------------------------------------------------------------------------");
14295                }
14296                if (dumpAll || dumpPackage != null) {
14297                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14298                    pw.println();
14299                    if (dumpAll) {
14300                        pw.println("-------------------------------------------------------------------------------");
14301                    }
14302                }
14303                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14304                pw.println();
14305                if (dumpAll) {
14306                    pw.println("-------------------------------------------------------------------------------");
14307                }
14308                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14309                pw.println();
14310                if (dumpAll) {
14311                    pw.println("-------------------------------------------------------------------------------");
14312                }
14313                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14314                        dumpPackage);
14315            }
14316            sdumper.dumpWithClient();
14317            pw.println();
14318            synchronized (this) {
14319                if (dumpAll) {
14320                    pw.println("-------------------------------------------------------------------------------");
14321                }
14322                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14323                pw.println();
14324                if (dumpAll) {
14325                    pw.println("-------------------------------------------------------------------------------");
14326                }
14327                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14328                if (mAssociations.size() > 0) {
14329                    pw.println();
14330                    if (dumpAll) {
14331                        pw.println("-------------------------------------------------------------------------------");
14332                    }
14333                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14334                }
14335                pw.println();
14336                if (dumpAll) {
14337                    pw.println("-------------------------------------------------------------------------------");
14338                }
14339                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14340            }
14341
14342        } else {
14343            synchronized (this) {
14344                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14345                pw.println();
14346                if (dumpAll) {
14347                    pw.println("-------------------------------------------------------------------------------");
14348                }
14349                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14350                pw.println();
14351                if (dumpAll) {
14352                    pw.println("-------------------------------------------------------------------------------");
14353                }
14354                if (dumpAll || dumpPackage != null) {
14355                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14356                    pw.println();
14357                    if (dumpAll) {
14358                        pw.println("-------------------------------------------------------------------------------");
14359                    }
14360                }
14361                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14362                pw.println();
14363                if (dumpAll) {
14364                    pw.println("-------------------------------------------------------------------------------");
14365                }
14366                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14367                pw.println();
14368                if (dumpAll) {
14369                    pw.println("-------------------------------------------------------------------------------");
14370                }
14371                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14372                        .dumpLocked();
14373                pw.println();
14374                if (dumpAll) {
14375                    pw.println("-------------------------------------------------------------------------------");
14376                }
14377                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14378                pw.println();
14379                if (dumpAll) {
14380                    pw.println("-------------------------------------------------------------------------------");
14381                }
14382                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14383                if (mAssociations.size() > 0) {
14384                    pw.println();
14385                    if (dumpAll) {
14386                        pw.println("-------------------------------------------------------------------------------");
14387                    }
14388                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14389                }
14390                pw.println();
14391                if (dumpAll) {
14392                    pw.println("-------------------------------------------------------------------------------");
14393                }
14394                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14395            }
14396        }
14397        Binder.restoreCallingIdentity(origId);
14398    }
14399
14400    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14401            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14402        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14403
14404        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14405                dumpPackage);
14406        boolean needSep = printedAnything;
14407
14408        boolean printed = ActivityStackSupervisor.printThisActivity(pw,
14409                mStackSupervisor.getResumedActivityLocked(),
14410                dumpPackage, needSep, "  ResumedActivity: ");
14411        if (printed) {
14412            printedAnything = true;
14413            needSep = false;
14414        }
14415
14416        if (dumpPackage == null) {
14417            if (needSep) {
14418                pw.println();
14419            }
14420            needSep = true;
14421            printedAnything = true;
14422            mStackSupervisor.dump(pw, "  ");
14423        }
14424
14425        if (!printedAnything) {
14426            pw.println("  (nothing)");
14427        }
14428    }
14429
14430    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14431            int opti, boolean dumpAll, String dumpPackage) {
14432        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14433
14434        boolean printedAnything = false;
14435
14436        if (mRecentTasks != null && mRecentTasks.size() > 0) {
14437            boolean printedHeader = false;
14438
14439            final int N = mRecentTasks.size();
14440            for (int i=0; i<N; i++) {
14441                TaskRecord tr = mRecentTasks.get(i);
14442                if (dumpPackage != null) {
14443                    if (tr.realActivity == null ||
14444                            !dumpPackage.equals(tr.realActivity.getPackageName())) {
14445                        continue;
14446                    }
14447                }
14448                if (!printedHeader) {
14449                    pw.println("  Recent tasks:");
14450                    printedHeader = true;
14451                    printedAnything = true;
14452                }
14453                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14454                        pw.println(tr);
14455                if (dumpAll) {
14456                    mRecentTasks.get(i).dump(pw, "    ");
14457                }
14458            }
14459        }
14460
14461        if (!printedAnything) {
14462            pw.println("  (nothing)");
14463        }
14464    }
14465
14466    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14467            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14468        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14469
14470        int dumpUid = 0;
14471        if (dumpPackage != null) {
14472            IPackageManager pm = AppGlobals.getPackageManager();
14473            try {
14474                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14475            } catch (RemoteException e) {
14476            }
14477        }
14478
14479        boolean printedAnything = false;
14480
14481        final long now = SystemClock.uptimeMillis();
14482
14483        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14484            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14485                    = mAssociations.valueAt(i1);
14486            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14487                SparseArray<ArrayMap<String, Association>> sourceUids
14488                        = targetComponents.valueAt(i2);
14489                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14490                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14491                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14492                        Association ass = sourceProcesses.valueAt(i4);
14493                        if (dumpPackage != null) {
14494                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14495                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14496                                continue;
14497                            }
14498                        }
14499                        printedAnything = true;
14500                        pw.print("  ");
14501                        pw.print(ass.mTargetProcess);
14502                        pw.print("/");
14503                        UserHandle.formatUid(pw, ass.mTargetUid);
14504                        pw.print(" <- ");
14505                        pw.print(ass.mSourceProcess);
14506                        pw.print("/");
14507                        UserHandle.formatUid(pw, ass.mSourceUid);
14508                        pw.println();
14509                        pw.print("    via ");
14510                        pw.print(ass.mTargetComponent.flattenToShortString());
14511                        pw.println();
14512                        pw.print("    ");
14513                        long dur = ass.mTime;
14514                        if (ass.mNesting > 0) {
14515                            dur += now - ass.mStartTime;
14516                        }
14517                        TimeUtils.formatDuration(dur, pw);
14518                        pw.print(" (");
14519                        pw.print(ass.mCount);
14520                        pw.print(" times)");
14521                        pw.print("  ");
14522                        for (int i=0; i<ass.mStateTimes.length; i++) {
14523                            long amt = ass.mStateTimes[i];
14524                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14525                                amt += now - ass.mLastStateUptime;
14526                            }
14527                            if (amt != 0) {
14528                                pw.print(" ");
14529                                pw.print(ProcessList.makeProcStateString(
14530                                            i + ActivityManager.MIN_PROCESS_STATE));
14531                                pw.print("=");
14532                                TimeUtils.formatDuration(amt, pw);
14533                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14534                                    pw.print("*");
14535                                }
14536                            }
14537                        }
14538                        pw.println();
14539                        if (ass.mNesting > 0) {
14540                            pw.print("    Currently active: ");
14541                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14542                            pw.println();
14543                        }
14544                    }
14545                }
14546            }
14547
14548        }
14549
14550        if (!printedAnything) {
14551            pw.println("  (nothing)");
14552        }
14553    }
14554
14555    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14556            String header, boolean needSep) {
14557        boolean printed = false;
14558        int whichAppId = -1;
14559        if (dumpPackage != null) {
14560            try {
14561                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14562                        dumpPackage, 0);
14563                whichAppId = UserHandle.getAppId(info.uid);
14564            } catch (NameNotFoundException e) {
14565                e.printStackTrace();
14566            }
14567        }
14568        for (int i=0; i<uids.size(); i++) {
14569            UidRecord uidRec = uids.valueAt(i);
14570            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14571                continue;
14572            }
14573            if (!printed) {
14574                printed = true;
14575                if (needSep) {
14576                    pw.println();
14577                }
14578                pw.print("  ");
14579                pw.println(header);
14580                needSep = true;
14581            }
14582            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14583            pw.print(": "); pw.println(uidRec);
14584        }
14585        return printed;
14586    }
14587
14588    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14589            int opti, boolean dumpAll, String dumpPackage) {
14590        boolean needSep = false;
14591        boolean printedAnything = false;
14592        int numPers = 0;
14593
14594        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14595
14596        if (dumpAll) {
14597            final int NP = mProcessNames.getMap().size();
14598            for (int ip=0; ip<NP; ip++) {
14599                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14600                final int NA = procs.size();
14601                for (int ia=0; ia<NA; ia++) {
14602                    ProcessRecord r = procs.valueAt(ia);
14603                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14604                        continue;
14605                    }
14606                    if (!needSep) {
14607                        pw.println("  All known processes:");
14608                        needSep = true;
14609                        printedAnything = true;
14610                    }
14611                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14612                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14613                        pw.print(" "); pw.println(r);
14614                    r.dump(pw, "    ");
14615                    if (r.persistent) {
14616                        numPers++;
14617                    }
14618                }
14619            }
14620        }
14621
14622        if (mIsolatedProcesses.size() > 0) {
14623            boolean printed = false;
14624            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14625                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14626                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14627                    continue;
14628                }
14629                if (!printed) {
14630                    if (needSep) {
14631                        pw.println();
14632                    }
14633                    pw.println("  Isolated process list (sorted by uid):");
14634                    printedAnything = true;
14635                    printed = true;
14636                    needSep = true;
14637                }
14638                pw.println(String.format("%sIsolated #%2d: %s",
14639                        "    ", i, r.toString()));
14640            }
14641        }
14642
14643        if (mActiveUids.size() > 0) {
14644            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14645                printedAnything = needSep = true;
14646            }
14647        }
14648        if (mValidateUids.size() > 0) {
14649            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14650                printedAnything = needSep = true;
14651            }
14652        }
14653
14654        if (mLruProcesses.size() > 0) {
14655            if (needSep) {
14656                pw.println();
14657            }
14658            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14659                    pw.print(" total, non-act at ");
14660                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14661                    pw.print(", non-svc at ");
14662                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14663                    pw.println("):");
14664            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14665            needSep = true;
14666            printedAnything = true;
14667        }
14668
14669        if (dumpAll || dumpPackage != null) {
14670            synchronized (mPidsSelfLocked) {
14671                boolean printed = false;
14672                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14673                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14674                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14675                        continue;
14676                    }
14677                    if (!printed) {
14678                        if (needSep) pw.println();
14679                        needSep = true;
14680                        pw.println("  PID mappings:");
14681                        printed = true;
14682                        printedAnything = true;
14683                    }
14684                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14685                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14686                }
14687            }
14688        }
14689
14690        if (mForegroundProcesses.size() > 0) {
14691            synchronized (mPidsSelfLocked) {
14692                boolean printed = false;
14693                for (int i=0; i<mForegroundProcesses.size(); i++) {
14694                    ProcessRecord r = mPidsSelfLocked.get(
14695                            mForegroundProcesses.valueAt(i).pid);
14696                    if (dumpPackage != null && (r == null
14697                            || !r.pkgList.containsKey(dumpPackage))) {
14698                        continue;
14699                    }
14700                    if (!printed) {
14701                        if (needSep) pw.println();
14702                        needSep = true;
14703                        pw.println("  Foreground Processes:");
14704                        printed = true;
14705                        printedAnything = true;
14706                    }
14707                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14708                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14709                }
14710            }
14711        }
14712
14713        if (mPersistentStartingProcesses.size() > 0) {
14714            if (needSep) pw.println();
14715            needSep = true;
14716            printedAnything = true;
14717            pw.println("  Persisent processes that are starting:");
14718            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14719                    "Starting Norm", "Restarting PERS", dumpPackage);
14720        }
14721
14722        if (mRemovedProcesses.size() > 0) {
14723            if (needSep) pw.println();
14724            needSep = true;
14725            printedAnything = true;
14726            pw.println("  Processes that are being removed:");
14727            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14728                    "Removed Norm", "Removed PERS", dumpPackage);
14729        }
14730
14731        if (mProcessesOnHold.size() > 0) {
14732            if (needSep) pw.println();
14733            needSep = true;
14734            printedAnything = true;
14735            pw.println("  Processes that are on old until the system is ready:");
14736            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14737                    "OnHold Norm", "OnHold PERS", dumpPackage);
14738        }
14739
14740        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14741
14742        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14743        if (needSep) {
14744            printedAnything = true;
14745        }
14746
14747        if (dumpPackage == null) {
14748            pw.println();
14749            needSep = false;
14750            mUserController.dump(pw, dumpAll);
14751        }
14752        if (mHomeProcess != null && (dumpPackage == null
14753                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14754            if (needSep) {
14755                pw.println();
14756                needSep = false;
14757            }
14758            pw.println("  mHomeProcess: " + mHomeProcess);
14759        }
14760        if (mPreviousProcess != null && (dumpPackage == null
14761                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14762            if (needSep) {
14763                pw.println();
14764                needSep = false;
14765            }
14766            pw.println("  mPreviousProcess: " + mPreviousProcess);
14767        }
14768        if (dumpAll) {
14769            StringBuilder sb = new StringBuilder(128);
14770            sb.append("  mPreviousProcessVisibleTime: ");
14771            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14772            pw.println(sb);
14773        }
14774        if (mHeavyWeightProcess != null && (dumpPackage == null
14775                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14776            if (needSep) {
14777                pw.println();
14778                needSep = false;
14779            }
14780            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14781        }
14782        if (dumpPackage == null) {
14783            pw.println("  mGlobalConfiguration: " + getGlobalConfiguration());
14784        }
14785        if (dumpAll) {
14786            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14787            if (mCompatModePackages.getPackages().size() > 0) {
14788                boolean printed = false;
14789                for (Map.Entry<String, Integer> entry
14790                        : mCompatModePackages.getPackages().entrySet()) {
14791                    String pkg = entry.getKey();
14792                    int mode = entry.getValue();
14793                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14794                        continue;
14795                    }
14796                    if (!printed) {
14797                        pw.println("  mScreenCompatPackages:");
14798                        printed = true;
14799                    }
14800                    pw.print("    "); pw.print(pkg); pw.print(": ");
14801                            pw.print(mode); pw.println();
14802                }
14803            }
14804        }
14805        if (dumpPackage == null) {
14806            pw.println("  mWakefulness="
14807                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14808            pw.println("  mSleepTokens=" + mSleepTokens);
14809            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14810                    + lockScreenShownToString());
14811            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14812            if (mRunningVoice != null) {
14813                pw.println("  mRunningVoice=" + mRunningVoice);
14814                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14815            }
14816        }
14817        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14818                || mOrigWaitForDebugger) {
14819            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14820                    || dumpPackage.equals(mOrigDebugApp)) {
14821                if (needSep) {
14822                    pw.println();
14823                    needSep = false;
14824                }
14825                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14826                        + " mDebugTransient=" + mDebugTransient
14827                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14828            }
14829        }
14830        if (mCurAppTimeTracker != null) {
14831            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14832        }
14833        if (mMemWatchProcesses.getMap().size() > 0) {
14834            pw.println("  Mem watch processes:");
14835            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14836                    = mMemWatchProcesses.getMap();
14837            for (int i=0; i<procs.size(); i++) {
14838                final String proc = procs.keyAt(i);
14839                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14840                for (int j=0; j<uids.size(); j++) {
14841                    if (needSep) {
14842                        pw.println();
14843                        needSep = false;
14844                    }
14845                    StringBuilder sb = new StringBuilder();
14846                    sb.append("    ").append(proc).append('/');
14847                    UserHandle.formatUid(sb, uids.keyAt(j));
14848                    Pair<Long, String> val = uids.valueAt(j);
14849                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14850                    if (val.second != null) {
14851                        sb.append(", report to ").append(val.second);
14852                    }
14853                    pw.println(sb.toString());
14854                }
14855            }
14856            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14857            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14858            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14859                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14860        }
14861        if (mTrackAllocationApp != null) {
14862            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14863                if (needSep) {
14864                    pw.println();
14865                    needSep = false;
14866                }
14867                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14868            }
14869        }
14870        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14871                || mProfileFd != null) {
14872            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14873                if (needSep) {
14874                    pw.println();
14875                    needSep = false;
14876                }
14877                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14878                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14879                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14880                        + mAutoStopProfiler);
14881                pw.println("  mProfileType=" + mProfileType);
14882            }
14883        }
14884        if (mNativeDebuggingApp != null) {
14885            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14886                if (needSep) {
14887                    pw.println();
14888                    needSep = false;
14889                }
14890                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14891            }
14892        }
14893        if (dumpPackage == null) {
14894            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14895                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14896                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14897            }
14898            if (mController != null) {
14899                pw.println("  mController=" + mController
14900                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14901            }
14902            if (dumpAll) {
14903                pw.println("  Total persistent processes: " + numPers);
14904                pw.println("  mProcessesReady=" + mProcessesReady
14905                        + " mSystemReady=" + mSystemReady
14906                        + " mBooted=" + mBooted
14907                        + " mFactoryTest=" + mFactoryTest);
14908                pw.println("  mBooting=" + mBooting
14909                        + " mCallFinishBooting=" + mCallFinishBooting
14910                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14911                pw.print("  mLastPowerCheckRealtime=");
14912                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14913                        pw.println("");
14914                pw.print("  mLastPowerCheckUptime=");
14915                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14916                        pw.println("");
14917                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14918                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14919                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14920                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14921                        + " (" + mLruProcesses.size() + " total)"
14922                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14923                        + " mNumServiceProcs=" + mNumServiceProcs
14924                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14925                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14926                        + " mLastMemoryLevel=" + mLastMemoryLevel
14927                        + " mLastNumProcesses=" + mLastNumProcesses);
14928                long now = SystemClock.uptimeMillis();
14929                pw.print("  mLastIdleTime=");
14930                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14931                        pw.print(" mLowRamSinceLastIdle=");
14932                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14933                        pw.println();
14934            }
14935        }
14936
14937        if (!printedAnything) {
14938            pw.println("  (nothing)");
14939        }
14940    }
14941
14942    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14943            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14944        if (mProcessesToGc.size() > 0) {
14945            boolean printed = false;
14946            long now = SystemClock.uptimeMillis();
14947            for (int i=0; i<mProcessesToGc.size(); i++) {
14948                ProcessRecord proc = mProcessesToGc.get(i);
14949                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14950                    continue;
14951                }
14952                if (!printed) {
14953                    if (needSep) pw.println();
14954                    needSep = true;
14955                    pw.println("  Processes that are waiting to GC:");
14956                    printed = true;
14957                }
14958                pw.print("    Process "); pw.println(proc);
14959                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14960                        pw.print(", last gced=");
14961                        pw.print(now-proc.lastRequestedGc);
14962                        pw.print(" ms ago, last lowMem=");
14963                        pw.print(now-proc.lastLowMemory);
14964                        pw.println(" ms ago");
14965
14966            }
14967        }
14968        return needSep;
14969    }
14970
14971    void printOomLevel(PrintWriter pw, String name, int adj) {
14972        pw.print("    ");
14973        if (adj >= 0) {
14974            pw.print(' ');
14975            if (adj < 10) pw.print(' ');
14976        } else {
14977            if (adj > -10) pw.print(' ');
14978        }
14979        pw.print(adj);
14980        pw.print(": ");
14981        pw.print(name);
14982        pw.print(" (");
14983        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14984        pw.println(")");
14985    }
14986
14987    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14988            int opti, boolean dumpAll) {
14989        boolean needSep = false;
14990
14991        if (mLruProcesses.size() > 0) {
14992            if (needSep) pw.println();
14993            needSep = true;
14994            pw.println("  OOM levels:");
14995            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14996            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14997            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14998            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14999            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
15000            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
15001            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
15002            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
15003            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
15004            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
15005            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
15006            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
15007            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
15008            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
15009
15010            if (needSep) pw.println();
15011            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
15012                    pw.print(" total, non-act at ");
15013                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15014                    pw.print(", non-svc at ");
15015                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15016                    pw.println("):");
15017            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
15018            needSep = true;
15019        }
15020
15021        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
15022
15023        pw.println();
15024        pw.println("  mHomeProcess: " + mHomeProcess);
15025        pw.println("  mPreviousProcess: " + mPreviousProcess);
15026        if (mHeavyWeightProcess != null) {
15027            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
15028        }
15029
15030        return true;
15031    }
15032
15033    /**
15034     * There are three ways to call this:
15035     *  - no provider specified: dump all the providers
15036     *  - a flattened component name that matched an existing provider was specified as the
15037     *    first arg: dump that one provider
15038     *  - the first arg isn't the flattened component name of an existing provider:
15039     *    dump all providers whose component contains the first arg as a substring
15040     */
15041    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15042            int opti, boolean dumpAll) {
15043        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
15044    }
15045
15046    static class ItemMatcher {
15047        ArrayList<ComponentName> components;
15048        ArrayList<String> strings;
15049        ArrayList<Integer> objects;
15050        boolean all;
15051
15052        ItemMatcher() {
15053            all = true;
15054        }
15055
15056        void build(String name) {
15057            ComponentName componentName = ComponentName.unflattenFromString(name);
15058            if (componentName != null) {
15059                if (components == null) {
15060                    components = new ArrayList<ComponentName>();
15061                }
15062                components.add(componentName);
15063                all = false;
15064            } else {
15065                int objectId = 0;
15066                // Not a '/' separated full component name; maybe an object ID?
15067                try {
15068                    objectId = Integer.parseInt(name, 16);
15069                    if (objects == null) {
15070                        objects = new ArrayList<Integer>();
15071                    }
15072                    objects.add(objectId);
15073                    all = false;
15074                } catch (RuntimeException e) {
15075                    // Not an integer; just do string match.
15076                    if (strings == null) {
15077                        strings = new ArrayList<String>();
15078                    }
15079                    strings.add(name);
15080                    all = false;
15081                }
15082            }
15083        }
15084
15085        int build(String[] args, int opti) {
15086            for (; opti<args.length; opti++) {
15087                String name = args[opti];
15088                if ("--".equals(name)) {
15089                    return opti+1;
15090                }
15091                build(name);
15092            }
15093            return opti;
15094        }
15095
15096        boolean match(Object object, ComponentName comp) {
15097            if (all) {
15098                return true;
15099            }
15100            if (components != null) {
15101                for (int i=0; i<components.size(); i++) {
15102                    if (components.get(i).equals(comp)) {
15103                        return true;
15104                    }
15105                }
15106            }
15107            if (objects != null) {
15108                for (int i=0; i<objects.size(); i++) {
15109                    if (System.identityHashCode(object) == objects.get(i)) {
15110                        return true;
15111                    }
15112                }
15113            }
15114            if (strings != null) {
15115                String flat = comp.flattenToString();
15116                for (int i=0; i<strings.size(); i++) {
15117                    if (flat.contains(strings.get(i))) {
15118                        return true;
15119                    }
15120                }
15121            }
15122            return false;
15123        }
15124    }
15125
15126    /**
15127     * There are three things that cmd can be:
15128     *  - a flattened component name that matches an existing activity
15129     *  - the cmd arg isn't the flattened component name of an existing activity:
15130     *    dump all activity whose component contains the cmd as a substring
15131     *  - A hex number of the ActivityRecord object instance.
15132     */
15133    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15134            int opti, boolean dumpAll, boolean dumpVisibleStacks) {
15135        ArrayList<ActivityRecord> activities;
15136
15137        synchronized (this) {
15138            activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacks);
15139        }
15140
15141        if (activities.size() <= 0) {
15142            return false;
15143        }
15144
15145        String[] newArgs = new String[args.length - opti];
15146        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15147
15148        TaskRecord lastTask = null;
15149        boolean needSep = false;
15150        for (int i=activities.size()-1; i>=0; i--) {
15151            ActivityRecord r = activities.get(i);
15152            if (needSep) {
15153                pw.println();
15154            }
15155            needSep = true;
15156            synchronized (this) {
15157                if (lastTask != r.task) {
15158                    lastTask = r.task;
15159                    pw.print("TASK "); pw.print(lastTask.affinity);
15160                            pw.print(" id="); pw.println(lastTask.taskId);
15161                    if (dumpAll) {
15162                        lastTask.dump(pw, "  ");
15163                    }
15164                }
15165            }
15166            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
15167        }
15168        return true;
15169    }
15170
15171    /**
15172     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
15173     * there is a thread associated with the activity.
15174     */
15175    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
15176            final ActivityRecord r, String[] args, boolean dumpAll) {
15177        String innerPrefix = prefix + "  ";
15178        synchronized (this) {
15179            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
15180                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
15181                    pw.print(" pid=");
15182                    if (r.app != null) pw.println(r.app.pid);
15183                    else pw.println("(not running)");
15184            if (dumpAll) {
15185                r.dump(pw, innerPrefix);
15186            }
15187        }
15188        if (r.app != null && r.app.thread != null) {
15189            // flush anything that is already in the PrintWriter since the thread is going
15190            // to write to the file descriptor directly
15191            pw.flush();
15192            try {
15193                TransferPipe tp = new TransferPipe();
15194                try {
15195                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
15196                            r.appToken, innerPrefix, args);
15197                    tp.go(fd);
15198                } finally {
15199                    tp.kill();
15200                }
15201            } catch (IOException e) {
15202                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
15203            } catch (RemoteException e) {
15204                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
15205            }
15206        }
15207    }
15208
15209    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15210            int opti, boolean dumpAll, String dumpPackage) {
15211        boolean needSep = false;
15212        boolean onlyHistory = false;
15213        boolean printedAnything = false;
15214
15215        if ("history".equals(dumpPackage)) {
15216            if (opti < args.length && "-s".equals(args[opti])) {
15217                dumpAll = false;
15218            }
15219            onlyHistory = true;
15220            dumpPackage = null;
15221        }
15222
15223        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
15224        if (!onlyHistory && dumpAll) {
15225            if (mRegisteredReceivers.size() > 0) {
15226                boolean printed = false;
15227                Iterator it = mRegisteredReceivers.values().iterator();
15228                while (it.hasNext()) {
15229                    ReceiverList r = (ReceiverList)it.next();
15230                    if (dumpPackage != null && (r.app == null ||
15231                            !dumpPackage.equals(r.app.info.packageName))) {
15232                        continue;
15233                    }
15234                    if (!printed) {
15235                        pw.println("  Registered Receivers:");
15236                        needSep = true;
15237                        printed = true;
15238                        printedAnything = true;
15239                    }
15240                    pw.print("  * "); pw.println(r);
15241                    r.dump(pw, "    ");
15242                }
15243            }
15244
15245            if (mReceiverResolver.dump(pw, needSep ?
15246                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
15247                    "    ", dumpPackage, false, false)) {
15248                needSep = true;
15249                printedAnything = true;
15250            }
15251        }
15252
15253        for (BroadcastQueue q : mBroadcastQueues) {
15254            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
15255            printedAnything |= needSep;
15256        }
15257
15258        needSep = true;
15259
15260        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15261            for (int user=0; user<mStickyBroadcasts.size(); user++) {
15262                if (needSep) {
15263                    pw.println();
15264                }
15265                needSep = true;
15266                printedAnything = true;
15267                pw.print("  Sticky broadcasts for user ");
15268                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15269                StringBuilder sb = new StringBuilder(128);
15270                for (Map.Entry<String, ArrayList<Intent>> ent
15271                        : mStickyBroadcasts.valueAt(user).entrySet()) {
15272                    pw.print("  * Sticky action "); pw.print(ent.getKey());
15273                    if (dumpAll) {
15274                        pw.println(":");
15275                        ArrayList<Intent> intents = ent.getValue();
15276                        final int N = intents.size();
15277                        for (int i=0; i<N; i++) {
15278                            sb.setLength(0);
15279                            sb.append("    Intent: ");
15280                            intents.get(i).toShortString(sb, false, true, false, false);
15281                            pw.println(sb.toString());
15282                            Bundle bundle = intents.get(i).getExtras();
15283                            if (bundle != null) {
15284                                pw.print("      ");
15285                                pw.println(bundle.toString());
15286                            }
15287                        }
15288                    } else {
15289                        pw.println("");
15290                    }
15291                }
15292            }
15293        }
15294
15295        if (!onlyHistory && dumpAll) {
15296            pw.println();
15297            for (BroadcastQueue queue : mBroadcastQueues) {
15298                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
15299                        + queue.mBroadcastsScheduled);
15300            }
15301            pw.println("  mHandler:");
15302            mHandler.dump(new PrintWriterPrinter(pw), "    ");
15303            needSep = true;
15304            printedAnything = true;
15305        }
15306
15307        if (!printedAnything) {
15308            pw.println("  (nothing)");
15309        }
15310    }
15311
15312    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15313            int opti, boolean dumpAll, String dumpPackage) {
15314        if (mCurBroadcastStats == null) {
15315            return;
15316        }
15317
15318        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15319        final long now = SystemClock.elapsedRealtime();
15320        if (mLastBroadcastStats != null) {
15321            pw.print("  Last stats (from ");
15322            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15323            pw.print(" to ");
15324            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15325            pw.print(", ");
15326            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15327                    - mLastBroadcastStats.mStartUptime, pw);
15328            pw.println(" uptime):");
15329            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15330                pw.println("    (nothing)");
15331            }
15332            pw.println();
15333        }
15334        pw.print("  Current stats (from ");
15335        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15336        pw.print(" to now, ");
15337        TimeUtils.formatDuration(SystemClock.uptimeMillis()
15338                - mCurBroadcastStats.mStartUptime, pw);
15339        pw.println(" uptime):");
15340        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15341            pw.println("    (nothing)");
15342        }
15343    }
15344
15345    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15346            int opti, boolean fullCheckin, String dumpPackage) {
15347        if (mCurBroadcastStats == null) {
15348            return;
15349        }
15350
15351        if (mLastBroadcastStats != null) {
15352            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15353            if (fullCheckin) {
15354                mLastBroadcastStats = null;
15355                return;
15356            }
15357        }
15358        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15359        if (fullCheckin) {
15360            mCurBroadcastStats = null;
15361        }
15362    }
15363
15364    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15365            int opti, boolean dumpAll, String dumpPackage) {
15366        boolean needSep;
15367        boolean printedAnything = false;
15368
15369        ItemMatcher matcher = new ItemMatcher();
15370        matcher.build(args, opti);
15371
15372        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15373
15374        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15375        printedAnything |= needSep;
15376
15377        if (mLaunchingProviders.size() > 0) {
15378            boolean printed = false;
15379            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15380                ContentProviderRecord r = mLaunchingProviders.get(i);
15381                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15382                    continue;
15383                }
15384                if (!printed) {
15385                    if (needSep) pw.println();
15386                    needSep = true;
15387                    pw.println("  Launching content providers:");
15388                    printed = true;
15389                    printedAnything = true;
15390                }
15391                pw.print("  Launching #"); pw.print(i); pw.print(": ");
15392                        pw.println(r);
15393            }
15394        }
15395
15396        if (!printedAnything) {
15397            pw.println("  (nothing)");
15398        }
15399    }
15400
15401    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15402            int opti, boolean dumpAll, String dumpPackage) {
15403        boolean needSep = false;
15404        boolean printedAnything = false;
15405
15406        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15407
15408        if (mGrantedUriPermissions.size() > 0) {
15409            boolean printed = false;
15410            int dumpUid = -2;
15411            if (dumpPackage != null) {
15412                try {
15413                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15414                            MATCH_UNINSTALLED_PACKAGES, 0);
15415                } catch (NameNotFoundException e) {
15416                    dumpUid = -1;
15417                }
15418            }
15419            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15420                int uid = mGrantedUriPermissions.keyAt(i);
15421                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15422                    continue;
15423                }
15424                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15425                if (!printed) {
15426                    if (needSep) pw.println();
15427                    needSep = true;
15428                    pw.println("  Granted Uri Permissions:");
15429                    printed = true;
15430                    printedAnything = true;
15431                }
15432                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15433                for (UriPermission perm : perms.values()) {
15434                    pw.print("    "); pw.println(perm);
15435                    if (dumpAll) {
15436                        perm.dump(pw, "      ");
15437                    }
15438                }
15439            }
15440        }
15441
15442        if (!printedAnything) {
15443            pw.println("  (nothing)");
15444        }
15445    }
15446
15447    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15448            int opti, boolean dumpAll, String dumpPackage) {
15449        boolean printed = false;
15450
15451        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15452
15453        if (mIntentSenderRecords.size() > 0) {
15454            Iterator<WeakReference<PendingIntentRecord>> it
15455                    = mIntentSenderRecords.values().iterator();
15456            while (it.hasNext()) {
15457                WeakReference<PendingIntentRecord> ref = it.next();
15458                PendingIntentRecord rec = ref != null ? ref.get(): null;
15459                if (dumpPackage != null && (rec == null
15460                        || !dumpPackage.equals(rec.key.packageName))) {
15461                    continue;
15462                }
15463                printed = true;
15464                if (rec != null) {
15465                    pw.print("  * "); pw.println(rec);
15466                    if (dumpAll) {
15467                        rec.dump(pw, "    ");
15468                    }
15469                } else {
15470                    pw.print("  * "); pw.println(ref);
15471                }
15472            }
15473        }
15474
15475        if (!printed) {
15476            pw.println("  (nothing)");
15477        }
15478    }
15479
15480    private static final int dumpProcessList(PrintWriter pw,
15481            ActivityManagerService service, List list,
15482            String prefix, String normalLabel, String persistentLabel,
15483            String dumpPackage) {
15484        int numPers = 0;
15485        final int N = list.size()-1;
15486        for (int i=N; i>=0; i--) {
15487            ProcessRecord r = (ProcessRecord)list.get(i);
15488            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15489                continue;
15490            }
15491            pw.println(String.format("%s%s #%2d: %s",
15492                    prefix, (r.persistent ? persistentLabel : normalLabel),
15493                    i, r.toString()));
15494            if (r.persistent) {
15495                numPers++;
15496            }
15497        }
15498        return numPers;
15499    }
15500
15501    private static final boolean dumpProcessOomList(PrintWriter pw,
15502            ActivityManagerService service, List<ProcessRecord> origList,
15503            String prefix, String normalLabel, String persistentLabel,
15504            boolean inclDetails, String dumpPackage) {
15505
15506        ArrayList<Pair<ProcessRecord, Integer>> list
15507                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15508        for (int i=0; i<origList.size(); i++) {
15509            ProcessRecord r = origList.get(i);
15510            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15511                continue;
15512            }
15513            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15514        }
15515
15516        if (list.size() <= 0) {
15517            return false;
15518        }
15519
15520        Comparator<Pair<ProcessRecord, Integer>> comparator
15521                = new Comparator<Pair<ProcessRecord, Integer>>() {
15522            @Override
15523            public int compare(Pair<ProcessRecord, Integer> object1,
15524                    Pair<ProcessRecord, Integer> object2) {
15525                if (object1.first.setAdj != object2.first.setAdj) {
15526                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15527                }
15528                if (object1.first.setProcState != object2.first.setProcState) {
15529                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15530                }
15531                if (object1.second.intValue() != object2.second.intValue()) {
15532                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15533                }
15534                return 0;
15535            }
15536        };
15537
15538        Collections.sort(list, comparator);
15539
15540        final long curRealtime = SystemClock.elapsedRealtime();
15541        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15542        final long curUptime = SystemClock.uptimeMillis();
15543        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15544
15545        for (int i=list.size()-1; i>=0; i--) {
15546            ProcessRecord r = list.get(i).first;
15547            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15548            char schedGroup;
15549            switch (r.setSchedGroup) {
15550                case ProcessList.SCHED_GROUP_BACKGROUND:
15551                    schedGroup = 'B';
15552                    break;
15553                case ProcessList.SCHED_GROUP_DEFAULT:
15554                    schedGroup = 'F';
15555                    break;
15556                case ProcessList.SCHED_GROUP_TOP_APP:
15557                    schedGroup = 'T';
15558                    break;
15559                default:
15560                    schedGroup = '?';
15561                    break;
15562            }
15563            char foreground;
15564            if (r.foregroundActivities) {
15565                foreground = 'A';
15566            } else if (r.foregroundServices) {
15567                foreground = 'S';
15568            } else {
15569                foreground = ' ';
15570            }
15571            String procState = ProcessList.makeProcStateString(r.curProcState);
15572            pw.print(prefix);
15573            pw.print(r.persistent ? persistentLabel : normalLabel);
15574            pw.print(" #");
15575            int num = (origList.size()-1)-list.get(i).second;
15576            if (num < 10) pw.print(' ');
15577            pw.print(num);
15578            pw.print(": ");
15579            pw.print(oomAdj);
15580            pw.print(' ');
15581            pw.print(schedGroup);
15582            pw.print('/');
15583            pw.print(foreground);
15584            pw.print('/');
15585            pw.print(procState);
15586            pw.print(" trm:");
15587            if (r.trimMemoryLevel < 10) pw.print(' ');
15588            pw.print(r.trimMemoryLevel);
15589            pw.print(' ');
15590            pw.print(r.toShortString());
15591            pw.print(" (");
15592            pw.print(r.adjType);
15593            pw.println(')');
15594            if (r.adjSource != null || r.adjTarget != null) {
15595                pw.print(prefix);
15596                pw.print("    ");
15597                if (r.adjTarget instanceof ComponentName) {
15598                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15599                } else if (r.adjTarget != null) {
15600                    pw.print(r.adjTarget.toString());
15601                } else {
15602                    pw.print("{null}");
15603                }
15604                pw.print("<=");
15605                if (r.adjSource instanceof ProcessRecord) {
15606                    pw.print("Proc{");
15607                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15608                    pw.println("}");
15609                } else if (r.adjSource != null) {
15610                    pw.println(r.adjSource.toString());
15611                } else {
15612                    pw.println("{null}");
15613                }
15614            }
15615            if (inclDetails) {
15616                pw.print(prefix);
15617                pw.print("    ");
15618                pw.print("oom: max="); pw.print(r.maxAdj);
15619                pw.print(" curRaw="); pw.print(r.curRawAdj);
15620                pw.print(" setRaw="); pw.print(r.setRawAdj);
15621                pw.print(" cur="); pw.print(r.curAdj);
15622                pw.print(" set="); pw.println(r.setAdj);
15623                pw.print(prefix);
15624                pw.print("    ");
15625                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15626                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15627                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15628                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15629                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15630                pw.println();
15631                pw.print(prefix);
15632                pw.print("    ");
15633                pw.print("cached="); pw.print(r.cached);
15634                pw.print(" empty="); pw.print(r.empty);
15635                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15636
15637                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15638                    if (r.lastWakeTime != 0) {
15639                        long wtime;
15640                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15641                        synchronized (stats) {
15642                            wtime = stats.getProcessWakeTime(r.info.uid,
15643                                    r.pid, curRealtime);
15644                        }
15645                        long timeUsed = wtime - r.lastWakeTime;
15646                        pw.print(prefix);
15647                        pw.print("    ");
15648                        pw.print("keep awake over ");
15649                        TimeUtils.formatDuration(realtimeSince, pw);
15650                        pw.print(" used ");
15651                        TimeUtils.formatDuration(timeUsed, pw);
15652                        pw.print(" (");
15653                        pw.print((timeUsed*100)/realtimeSince);
15654                        pw.println("%)");
15655                    }
15656                    if (r.lastCpuTime != 0) {
15657                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15658                        pw.print(prefix);
15659                        pw.print("    ");
15660                        pw.print("run cpu over ");
15661                        TimeUtils.formatDuration(uptimeSince, pw);
15662                        pw.print(" used ");
15663                        TimeUtils.formatDuration(timeUsed, pw);
15664                        pw.print(" (");
15665                        pw.print((timeUsed*100)/uptimeSince);
15666                        pw.println("%)");
15667                    }
15668                }
15669            }
15670        }
15671        return true;
15672    }
15673
15674    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15675            String[] args) {
15676        ArrayList<ProcessRecord> procs;
15677        synchronized (this) {
15678            if (args != null && args.length > start
15679                    && args[start].charAt(0) != '-') {
15680                procs = new ArrayList<ProcessRecord>();
15681                int pid = -1;
15682                try {
15683                    pid = Integer.parseInt(args[start]);
15684                } catch (NumberFormatException e) {
15685                }
15686                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15687                    ProcessRecord proc = mLruProcesses.get(i);
15688                    if (proc.pid == pid) {
15689                        procs.add(proc);
15690                    } else if (allPkgs && proc.pkgList != null
15691                            && proc.pkgList.containsKey(args[start])) {
15692                        procs.add(proc);
15693                    } else if (proc.processName.equals(args[start])) {
15694                        procs.add(proc);
15695                    }
15696                }
15697                if (procs.size() <= 0) {
15698                    return null;
15699                }
15700            } else {
15701                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15702            }
15703        }
15704        return procs;
15705    }
15706
15707    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15708            PrintWriter pw, String[] args) {
15709        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15710        if (procs == null) {
15711            pw.println("No process found for: " + args[0]);
15712            return;
15713        }
15714
15715        long uptime = SystemClock.uptimeMillis();
15716        long realtime = SystemClock.elapsedRealtime();
15717        pw.println("Applications Graphics Acceleration Info:");
15718        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15719
15720        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15721            ProcessRecord r = procs.get(i);
15722            if (r.thread != null) {
15723                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15724                pw.flush();
15725                try {
15726                    TransferPipe tp = new TransferPipe();
15727                    try {
15728                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15729                        tp.go(fd);
15730                    } finally {
15731                        tp.kill();
15732                    }
15733                } catch (IOException e) {
15734                    pw.println("Failure while dumping the app: " + r);
15735                    pw.flush();
15736                } catch (RemoteException e) {
15737                    pw.println("Got a RemoteException while dumping the app " + r);
15738                    pw.flush();
15739                }
15740            }
15741        }
15742    }
15743
15744    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15745        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15746        if (procs == null) {
15747            pw.println("No process found for: " + args[0]);
15748            return;
15749        }
15750
15751        pw.println("Applications Database Info:");
15752
15753        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15754            ProcessRecord r = procs.get(i);
15755            if (r.thread != null) {
15756                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15757                pw.flush();
15758                try {
15759                    TransferPipe tp = new TransferPipe();
15760                    try {
15761                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15762                        tp.go(fd);
15763                    } finally {
15764                        tp.kill();
15765                    }
15766                } catch (IOException e) {
15767                    pw.println("Failure while dumping the app: " + r);
15768                    pw.flush();
15769                } catch (RemoteException e) {
15770                    pw.println("Got a RemoteException while dumping the app " + r);
15771                    pw.flush();
15772                }
15773            }
15774        }
15775    }
15776
15777    final static class MemItem {
15778        final boolean isProc;
15779        final String label;
15780        final String shortLabel;
15781        final long pss;
15782        final long swapPss;
15783        final int id;
15784        final boolean hasActivities;
15785        ArrayList<MemItem> subitems;
15786
15787        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15788                boolean _hasActivities) {
15789            isProc = true;
15790            label = _label;
15791            shortLabel = _shortLabel;
15792            pss = _pss;
15793            swapPss = _swapPss;
15794            id = _id;
15795            hasActivities = _hasActivities;
15796        }
15797
15798        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15799            isProc = false;
15800            label = _label;
15801            shortLabel = _shortLabel;
15802            pss = _pss;
15803            swapPss = _swapPss;
15804            id = _id;
15805            hasActivities = false;
15806        }
15807    }
15808
15809    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15810            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15811        if (sort && !isCompact) {
15812            Collections.sort(items, new Comparator<MemItem>() {
15813                @Override
15814                public int compare(MemItem lhs, MemItem rhs) {
15815                    if (lhs.pss < rhs.pss) {
15816                        return 1;
15817                    } else if (lhs.pss > rhs.pss) {
15818                        return -1;
15819                    }
15820                    return 0;
15821                }
15822            });
15823        }
15824
15825        for (int i=0; i<items.size(); i++) {
15826            MemItem mi = items.get(i);
15827            if (!isCompact) {
15828                if (dumpSwapPss) {
15829                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15830                            mi.label, stringifyKBSize(mi.swapPss));
15831                } else {
15832                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15833                }
15834            } else if (mi.isProc) {
15835                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15836                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15837                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15838                pw.println(mi.hasActivities ? ",a" : ",e");
15839            } else {
15840                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15841                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15842            }
15843            if (mi.subitems != null) {
15844                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15845                        true, isCompact, dumpSwapPss);
15846            }
15847        }
15848    }
15849
15850    // These are in KB.
15851    static final long[] DUMP_MEM_BUCKETS = new long[] {
15852        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15853        120*1024, 160*1024, 200*1024,
15854        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15855        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15856    };
15857
15858    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15859            boolean stackLike) {
15860        int start = label.lastIndexOf('.');
15861        if (start >= 0) start++;
15862        else start = 0;
15863        int end = label.length();
15864        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15865            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15866                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15867                out.append(bucket);
15868                out.append(stackLike ? "MB." : "MB ");
15869                out.append(label, start, end);
15870                return;
15871            }
15872        }
15873        out.append(memKB/1024);
15874        out.append(stackLike ? "MB." : "MB ");
15875        out.append(label, start, end);
15876    }
15877
15878    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15879            ProcessList.NATIVE_ADJ,
15880            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15881            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15882            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15883            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15884            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15885            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15886    };
15887    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15888            "Native",
15889            "System", "Persistent", "Persistent Service", "Foreground",
15890            "Visible", "Perceptible",
15891            "Heavy Weight", "Backup",
15892            "A Services", "Home",
15893            "Previous", "B Services", "Cached"
15894    };
15895    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15896            "native",
15897            "sys", "pers", "persvc", "fore",
15898            "vis", "percept",
15899            "heavy", "backup",
15900            "servicea", "home",
15901            "prev", "serviceb", "cached"
15902    };
15903
15904    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15905            long realtime, boolean isCheckinRequest, boolean isCompact) {
15906        if (isCompact) {
15907            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15908        }
15909        if (isCheckinRequest || isCompact) {
15910            // short checkin version
15911            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15912        } else {
15913            pw.println("Applications Memory Usage (in Kilobytes):");
15914            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15915        }
15916    }
15917
15918    private static final int KSM_SHARED = 0;
15919    private static final int KSM_SHARING = 1;
15920    private static final int KSM_UNSHARED = 2;
15921    private static final int KSM_VOLATILE = 3;
15922
15923    private final long[] getKsmInfo() {
15924        long[] longOut = new long[4];
15925        final int[] SINGLE_LONG_FORMAT = new int[] {
15926            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15927        };
15928        long[] longTmp = new long[1];
15929        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15930                SINGLE_LONG_FORMAT, null, longTmp, null);
15931        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15932        longTmp[0] = 0;
15933        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15934                SINGLE_LONG_FORMAT, null, longTmp, null);
15935        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15936        longTmp[0] = 0;
15937        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15938                SINGLE_LONG_FORMAT, null, longTmp, null);
15939        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15940        longTmp[0] = 0;
15941        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15942                SINGLE_LONG_FORMAT, null, longTmp, null);
15943        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15944        return longOut;
15945    }
15946
15947    private static String stringifySize(long size, int order) {
15948        Locale locale = Locale.US;
15949        switch (order) {
15950            case 1:
15951                return String.format(locale, "%,13d", size);
15952            case 1024:
15953                return String.format(locale, "%,9dK", size / 1024);
15954            case 1024 * 1024:
15955                return String.format(locale, "%,5dM", size / 1024 / 1024);
15956            case 1024 * 1024 * 1024:
15957                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15958            default:
15959                throw new IllegalArgumentException("Invalid size order");
15960        }
15961    }
15962
15963    private static String stringifyKBSize(long size) {
15964        return stringifySize(size * 1024, 1024);
15965    }
15966
15967    // Update this version number in case you change the 'compact' format
15968    private static final int MEMINFO_COMPACT_VERSION = 1;
15969
15970    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15971            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15972        boolean dumpDetails = false;
15973        boolean dumpFullDetails = false;
15974        boolean dumpDalvik = false;
15975        boolean dumpSummaryOnly = false;
15976        boolean dumpUnreachable = false;
15977        boolean oomOnly = false;
15978        boolean isCompact = false;
15979        boolean localOnly = false;
15980        boolean packages = false;
15981        boolean isCheckinRequest = false;
15982        boolean dumpSwapPss = false;
15983
15984        int opti = 0;
15985        while (opti < args.length) {
15986            String opt = args[opti];
15987            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15988                break;
15989            }
15990            opti++;
15991            if ("-a".equals(opt)) {
15992                dumpDetails = true;
15993                dumpFullDetails = true;
15994                dumpDalvik = true;
15995                dumpSwapPss = true;
15996            } else if ("-d".equals(opt)) {
15997                dumpDalvik = true;
15998            } else if ("-c".equals(opt)) {
15999                isCompact = true;
16000            } else if ("-s".equals(opt)) {
16001                dumpDetails = true;
16002                dumpSummaryOnly = true;
16003            } else if ("-S".equals(opt)) {
16004                dumpSwapPss = true;
16005            } else if ("--unreachable".equals(opt)) {
16006                dumpUnreachable = true;
16007            } else if ("--oom".equals(opt)) {
16008                oomOnly = true;
16009            } else if ("--local".equals(opt)) {
16010                localOnly = true;
16011            } else if ("--package".equals(opt)) {
16012                packages = true;
16013            } else if ("--checkin".equals(opt)) {
16014                isCheckinRequest = true;
16015
16016            } else if ("-h".equals(opt)) {
16017                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
16018                pw.println("  -a: include all available information for each process.");
16019                pw.println("  -d: include dalvik details.");
16020                pw.println("  -c: dump in a compact machine-parseable representation.");
16021                pw.println("  -s: dump only summary of application memory usage.");
16022                pw.println("  -S: dump also SwapPss.");
16023                pw.println("  --oom: only show processes organized by oom adj.");
16024                pw.println("  --local: only collect details locally, don't call process.");
16025                pw.println("  --package: interpret process arg as package, dumping all");
16026                pw.println("             processes that have loaded that package.");
16027                pw.println("  --checkin: dump data for a checkin");
16028                pw.println("If [process] is specified it can be the name or ");
16029                pw.println("pid of a specific process to dump.");
16030                return;
16031            } else {
16032                pw.println("Unknown argument: " + opt + "; use -h for help");
16033            }
16034        }
16035
16036        long uptime = SystemClock.uptimeMillis();
16037        long realtime = SystemClock.elapsedRealtime();
16038        final long[] tmpLong = new long[1];
16039
16040        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
16041        if (procs == null) {
16042            // No Java processes.  Maybe they want to print a native process.
16043            if (args != null && args.length > opti
16044                    && args[opti].charAt(0) != '-') {
16045                ArrayList<ProcessCpuTracker.Stats> nativeProcs
16046                        = new ArrayList<ProcessCpuTracker.Stats>();
16047                updateCpuStatsNow();
16048                int findPid = -1;
16049                try {
16050                    findPid = Integer.parseInt(args[opti]);
16051                } catch (NumberFormatException e) {
16052                }
16053                synchronized (mProcessCpuTracker) {
16054                    final int N = mProcessCpuTracker.countStats();
16055                    for (int i=0; i<N; i++) {
16056                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16057                        if (st.pid == findPid || (st.baseName != null
16058                                && st.baseName.equals(args[opti]))) {
16059                            nativeProcs.add(st);
16060                        }
16061                    }
16062                }
16063                if (nativeProcs.size() > 0) {
16064                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
16065                            isCompact);
16066                    Debug.MemoryInfo mi = null;
16067                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
16068                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
16069                        final int pid = r.pid;
16070                        if (!isCheckinRequest && dumpDetails) {
16071                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
16072                        }
16073                        if (mi == null) {
16074                            mi = new Debug.MemoryInfo();
16075                        }
16076                        if (dumpDetails || (!brief && !oomOnly)) {
16077                            Debug.getMemoryInfo(pid, mi);
16078                        } else {
16079                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16080                            mi.dalvikPrivateDirty = (int)tmpLong[0];
16081                        }
16082                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16083                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
16084                        if (isCheckinRequest) {
16085                            pw.println();
16086                        }
16087                    }
16088                    return;
16089                }
16090            }
16091            pw.println("No process found for: " + args[opti]);
16092            return;
16093        }
16094
16095        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
16096            dumpDetails = true;
16097        }
16098
16099        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
16100
16101        String[] innerArgs = new String[args.length-opti];
16102        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
16103
16104        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
16105        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
16106        long nativePss = 0;
16107        long nativeSwapPss = 0;
16108        long dalvikPss = 0;
16109        long dalvikSwapPss = 0;
16110        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16111                EmptyArray.LONG;
16112        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16113                EmptyArray.LONG;
16114        long otherPss = 0;
16115        long otherSwapPss = 0;
16116        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16117        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16118
16119        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16120        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16121        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
16122                new ArrayList[DUMP_MEM_OOM_LABEL.length];
16123
16124        long totalPss = 0;
16125        long totalSwapPss = 0;
16126        long cachedPss = 0;
16127        long cachedSwapPss = 0;
16128        boolean hasSwapPss = false;
16129
16130        Debug.MemoryInfo mi = null;
16131        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16132            final ProcessRecord r = procs.get(i);
16133            final IApplicationThread thread;
16134            final int pid;
16135            final int oomAdj;
16136            final boolean hasActivities;
16137            synchronized (this) {
16138                thread = r.thread;
16139                pid = r.pid;
16140                oomAdj = r.getSetAdjWithServices();
16141                hasActivities = r.activities.size() > 0;
16142            }
16143            if (thread != null) {
16144                if (!isCheckinRequest && dumpDetails) {
16145                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
16146                }
16147                if (mi == null) {
16148                    mi = new Debug.MemoryInfo();
16149                }
16150                if (dumpDetails || (!brief && !oomOnly)) {
16151                    Debug.getMemoryInfo(pid, mi);
16152                    hasSwapPss = mi.hasSwappedOutPss;
16153                } else {
16154                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16155                    mi.dalvikPrivateDirty = (int)tmpLong[0];
16156                }
16157                if (dumpDetails) {
16158                    if (localOnly) {
16159                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16160                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
16161                        if (isCheckinRequest) {
16162                            pw.println();
16163                        }
16164                    } else {
16165                        try {
16166                            pw.flush();
16167                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
16168                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
16169                        } catch (RemoteException e) {
16170                            if (!isCheckinRequest) {
16171                                pw.println("Got RemoteException!");
16172                                pw.flush();
16173                            }
16174                        }
16175                    }
16176                }
16177
16178                final long myTotalPss = mi.getTotalPss();
16179                final long myTotalUss = mi.getTotalUss();
16180                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16181
16182                synchronized (this) {
16183                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
16184                        // Record this for posterity if the process has been stable.
16185                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
16186                    }
16187                }
16188
16189                if (!isCheckinRequest && mi != null) {
16190                    totalPss += myTotalPss;
16191                    totalSwapPss += myTotalSwapPss;
16192                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
16193                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
16194                            myTotalSwapPss, pid, hasActivities);
16195                    procMems.add(pssItem);
16196                    procMemsMap.put(pid, pssItem);
16197
16198                    nativePss += mi.nativePss;
16199                    nativeSwapPss += mi.nativeSwappedOutPss;
16200                    dalvikPss += mi.dalvikPss;
16201                    dalvikSwapPss += mi.dalvikSwappedOutPss;
16202                    for (int j=0; j<dalvikSubitemPss.length; j++) {
16203                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16204                        dalvikSubitemSwapPss[j] +=
16205                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16206                    }
16207                    otherPss += mi.otherPss;
16208                    otherSwapPss += mi.otherSwappedOutPss;
16209                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16210                        long mem = mi.getOtherPss(j);
16211                        miscPss[j] += mem;
16212                        otherPss -= mem;
16213                        mem = mi.getOtherSwappedOutPss(j);
16214                        miscSwapPss[j] += mem;
16215                        otherSwapPss -= mem;
16216                    }
16217
16218                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16219                        cachedPss += myTotalPss;
16220                        cachedSwapPss += myTotalSwapPss;
16221                    }
16222
16223                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
16224                        if (oomIndex == (oomPss.length - 1)
16225                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
16226                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
16227                            oomPss[oomIndex] += myTotalPss;
16228                            oomSwapPss[oomIndex] += myTotalSwapPss;
16229                            if (oomProcs[oomIndex] == null) {
16230                                oomProcs[oomIndex] = new ArrayList<MemItem>();
16231                            }
16232                            oomProcs[oomIndex].add(pssItem);
16233                            break;
16234                        }
16235                    }
16236                }
16237            }
16238        }
16239
16240        long nativeProcTotalPss = 0;
16241
16242        if (!isCheckinRequest && procs.size() > 1 && !packages) {
16243            // If we are showing aggregations, also look for native processes to
16244            // include so that our aggregations are more accurate.
16245            updateCpuStatsNow();
16246            mi = null;
16247            synchronized (mProcessCpuTracker) {
16248                final int N = mProcessCpuTracker.countStats();
16249                for (int i=0; i<N; i++) {
16250                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16251                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
16252                        if (mi == null) {
16253                            mi = new Debug.MemoryInfo();
16254                        }
16255                        if (!brief && !oomOnly) {
16256                            Debug.getMemoryInfo(st.pid, mi);
16257                        } else {
16258                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
16259                            mi.nativePrivateDirty = (int)tmpLong[0];
16260                        }
16261
16262                        final long myTotalPss = mi.getTotalPss();
16263                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16264                        totalPss += myTotalPss;
16265                        nativeProcTotalPss += myTotalPss;
16266
16267                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16268                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16269                        procMems.add(pssItem);
16270
16271                        nativePss += mi.nativePss;
16272                        nativeSwapPss += mi.nativeSwappedOutPss;
16273                        dalvikPss += mi.dalvikPss;
16274                        dalvikSwapPss += mi.dalvikSwappedOutPss;
16275                        for (int j=0; j<dalvikSubitemPss.length; j++) {
16276                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16277                            dalvikSubitemSwapPss[j] +=
16278                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16279                        }
16280                        otherPss += mi.otherPss;
16281                        otherSwapPss += mi.otherSwappedOutPss;
16282                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16283                            long mem = mi.getOtherPss(j);
16284                            miscPss[j] += mem;
16285                            otherPss -= mem;
16286                            mem = mi.getOtherSwappedOutPss(j);
16287                            miscSwapPss[j] += mem;
16288                            otherSwapPss -= mem;
16289                        }
16290                        oomPss[0] += myTotalPss;
16291                        oomSwapPss[0] += myTotalSwapPss;
16292                        if (oomProcs[0] == null) {
16293                            oomProcs[0] = new ArrayList<MemItem>();
16294                        }
16295                        oomProcs[0].add(pssItem);
16296                    }
16297                }
16298            }
16299
16300            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16301
16302            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16303            final MemItem dalvikItem =
16304                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16305            if (dalvikSubitemPss.length > 0) {
16306                dalvikItem.subitems = new ArrayList<MemItem>();
16307                for (int j=0; j<dalvikSubitemPss.length; j++) {
16308                    final String name = Debug.MemoryInfo.getOtherLabel(
16309                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
16310                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16311                                    dalvikSubitemSwapPss[j], j));
16312                }
16313            }
16314            catMems.add(dalvikItem);
16315            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16316            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16317                String label = Debug.MemoryInfo.getOtherLabel(j);
16318                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16319            }
16320
16321            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16322            for (int j=0; j<oomPss.length; j++) {
16323                if (oomPss[j] != 0) {
16324                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16325                            : DUMP_MEM_OOM_LABEL[j];
16326                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16327                            DUMP_MEM_OOM_ADJ[j]);
16328                    item.subitems = oomProcs[j];
16329                    oomMems.add(item);
16330                }
16331            }
16332
16333            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16334            if (!brief && !oomOnly && !isCompact) {
16335                pw.println();
16336                pw.println("Total PSS by process:");
16337                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
16338                pw.println();
16339            }
16340            if (!isCompact) {
16341                pw.println("Total PSS by OOM adjustment:");
16342            }
16343            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
16344            if (!brief && !oomOnly) {
16345                PrintWriter out = categoryPw != null ? categoryPw : pw;
16346                if (!isCompact) {
16347                    out.println();
16348                    out.println("Total PSS by category:");
16349                }
16350                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
16351            }
16352            if (!isCompact) {
16353                pw.println();
16354            }
16355            MemInfoReader memInfo = new MemInfoReader();
16356            memInfo.readMemInfo();
16357            if (nativeProcTotalPss > 0) {
16358                synchronized (this) {
16359                    final long cachedKb = memInfo.getCachedSizeKb();
16360                    final long freeKb = memInfo.getFreeSizeKb();
16361                    final long zramKb = memInfo.getZramTotalSizeKb();
16362                    final long kernelKb = memInfo.getKernelUsedSizeKb();
16363                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16364                            kernelKb*1024, nativeProcTotalPss*1024);
16365                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16366                            nativeProcTotalPss);
16367                }
16368            }
16369            if (!brief) {
16370                if (!isCompact) {
16371                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16372                    pw.print(" (status ");
16373                    switch (mLastMemoryLevel) {
16374                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16375                            pw.println("normal)");
16376                            break;
16377                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16378                            pw.println("moderate)");
16379                            break;
16380                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
16381                            pw.println("low)");
16382                            break;
16383                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16384                            pw.println("critical)");
16385                            break;
16386                        default:
16387                            pw.print(mLastMemoryLevel);
16388                            pw.println(")");
16389                            break;
16390                    }
16391                    pw.print(" Free RAM: ");
16392                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16393                            + memInfo.getFreeSizeKb()));
16394                    pw.print(" (");
16395                    pw.print(stringifyKBSize(cachedPss));
16396                    pw.print(" cached pss + ");
16397                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16398                    pw.print(" cached kernel + ");
16399                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16400                    pw.println(" free)");
16401                } else {
16402                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16403                    pw.print(cachedPss + memInfo.getCachedSizeKb()
16404                            + memInfo.getFreeSizeKb()); pw.print(",");
16405                    pw.println(totalPss - cachedPss);
16406                }
16407            }
16408            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16409                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16410                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16411            if (!isCompact) {
16412                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16413                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16414                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16415                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16416                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16417            } else {
16418                pw.print("lostram,"); pw.println(lostRAM);
16419            }
16420            if (!brief) {
16421                if (memInfo.getZramTotalSizeKb() != 0) {
16422                    if (!isCompact) {
16423                        pw.print("     ZRAM: ");
16424                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16425                                pw.print(" physical used for ");
16426                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16427                                        - memInfo.getSwapFreeSizeKb()));
16428                                pw.print(" in swap (");
16429                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16430                                pw.println(" total swap)");
16431                    } else {
16432                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16433                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16434                                pw.println(memInfo.getSwapFreeSizeKb());
16435                    }
16436                }
16437                final long[] ksm = getKsmInfo();
16438                if (!isCompact) {
16439                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16440                            || ksm[KSM_VOLATILE] != 0) {
16441                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16442                                pw.print(" saved from shared ");
16443                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16444                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16445                                pw.print(" unshared; ");
16446                                pw.print(stringifyKBSize(
16447                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
16448                    }
16449                    pw.print("   Tuning: ");
16450                    pw.print(ActivityManager.staticGetMemoryClass());
16451                    pw.print(" (large ");
16452                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16453                    pw.print("), oom ");
16454                    pw.print(stringifySize(
16455                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16456                    pw.print(", restore limit ");
16457                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16458                    if (ActivityManager.isLowRamDeviceStatic()) {
16459                        pw.print(" (low-ram)");
16460                    }
16461                    if (ActivityManager.isHighEndGfx()) {
16462                        pw.print(" (high-end-gfx)");
16463                    }
16464                    pw.println();
16465                } else {
16466                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16467                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16468                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16469                    pw.print("tuning,");
16470                    pw.print(ActivityManager.staticGetMemoryClass());
16471                    pw.print(',');
16472                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16473                    pw.print(',');
16474                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16475                    if (ActivityManager.isLowRamDeviceStatic()) {
16476                        pw.print(",low-ram");
16477                    }
16478                    if (ActivityManager.isHighEndGfx()) {
16479                        pw.print(",high-end-gfx");
16480                    }
16481                    pw.println();
16482                }
16483            }
16484        }
16485    }
16486
16487    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16488            long memtrack, String name) {
16489        sb.append("  ");
16490        sb.append(ProcessList.makeOomAdjString(oomAdj));
16491        sb.append(' ');
16492        sb.append(ProcessList.makeProcStateString(procState));
16493        sb.append(' ');
16494        ProcessList.appendRamKb(sb, pss);
16495        sb.append(": ");
16496        sb.append(name);
16497        if (memtrack > 0) {
16498            sb.append(" (");
16499            sb.append(stringifyKBSize(memtrack));
16500            sb.append(" memtrack)");
16501        }
16502    }
16503
16504    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16505        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16506        sb.append(" (pid ");
16507        sb.append(mi.pid);
16508        sb.append(") ");
16509        sb.append(mi.adjType);
16510        sb.append('\n');
16511        if (mi.adjReason != null) {
16512            sb.append("                      ");
16513            sb.append(mi.adjReason);
16514            sb.append('\n');
16515        }
16516    }
16517
16518    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16519        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16520        for (int i=0, N=memInfos.size(); i<N; i++) {
16521            ProcessMemInfo mi = memInfos.get(i);
16522            infoMap.put(mi.pid, mi);
16523        }
16524        updateCpuStatsNow();
16525        long[] memtrackTmp = new long[1];
16526        final List<ProcessCpuTracker.Stats> stats;
16527        // Get a list of Stats that have vsize > 0
16528        synchronized (mProcessCpuTracker) {
16529            stats = mProcessCpuTracker.getStats((st) -> {
16530                return st.vsize > 0;
16531            });
16532        }
16533        final int statsCount = stats.size();
16534        for (int i = 0; i < statsCount; i++) {
16535            ProcessCpuTracker.Stats st = stats.get(i);
16536            long pss = Debug.getPss(st.pid, null, memtrackTmp);
16537            if (pss > 0) {
16538                if (infoMap.indexOfKey(st.pid) < 0) {
16539                    ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16540                            ProcessList.NATIVE_ADJ, -1, "native", null);
16541                    mi.pss = pss;
16542                    mi.memtrack = memtrackTmp[0];
16543                    memInfos.add(mi);
16544                }
16545            }
16546        }
16547
16548        long totalPss = 0;
16549        long totalMemtrack = 0;
16550        for (int i=0, N=memInfos.size(); i<N; i++) {
16551            ProcessMemInfo mi = memInfos.get(i);
16552            if (mi.pss == 0) {
16553                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16554                mi.memtrack = memtrackTmp[0];
16555            }
16556            totalPss += mi.pss;
16557            totalMemtrack += mi.memtrack;
16558        }
16559        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16560            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16561                if (lhs.oomAdj != rhs.oomAdj) {
16562                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16563                }
16564                if (lhs.pss != rhs.pss) {
16565                    return lhs.pss < rhs.pss ? 1 : -1;
16566                }
16567                return 0;
16568            }
16569        });
16570
16571        StringBuilder tag = new StringBuilder(128);
16572        StringBuilder stack = new StringBuilder(128);
16573        tag.append("Low on memory -- ");
16574        appendMemBucket(tag, totalPss, "total", false);
16575        appendMemBucket(stack, totalPss, "total", true);
16576
16577        StringBuilder fullNativeBuilder = new StringBuilder(1024);
16578        StringBuilder shortNativeBuilder = new StringBuilder(1024);
16579        StringBuilder fullJavaBuilder = new StringBuilder(1024);
16580
16581        boolean firstLine = true;
16582        int lastOomAdj = Integer.MIN_VALUE;
16583        long extraNativeRam = 0;
16584        long extraNativeMemtrack = 0;
16585        long cachedPss = 0;
16586        for (int i=0, N=memInfos.size(); i<N; i++) {
16587            ProcessMemInfo mi = memInfos.get(i);
16588
16589            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16590                cachedPss += mi.pss;
16591            }
16592
16593            if (mi.oomAdj != ProcessList.NATIVE_ADJ
16594                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
16595                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
16596                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16597                if (lastOomAdj != mi.oomAdj) {
16598                    lastOomAdj = mi.oomAdj;
16599                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16600                        tag.append(" / ");
16601                    }
16602                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16603                        if (firstLine) {
16604                            stack.append(":");
16605                            firstLine = false;
16606                        }
16607                        stack.append("\n\t at ");
16608                    } else {
16609                        stack.append("$");
16610                    }
16611                } else {
16612                    tag.append(" ");
16613                    stack.append("$");
16614                }
16615                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16616                    appendMemBucket(tag, mi.pss, mi.name, false);
16617                }
16618                appendMemBucket(stack, mi.pss, mi.name, true);
16619                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16620                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16621                    stack.append("(");
16622                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16623                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16624                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16625                            stack.append(":");
16626                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16627                        }
16628                    }
16629                    stack.append(")");
16630                }
16631            }
16632
16633            appendMemInfo(fullNativeBuilder, mi);
16634            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16635                // The short form only has native processes that are >= 512K.
16636                if (mi.pss >= 512) {
16637                    appendMemInfo(shortNativeBuilder, mi);
16638                } else {
16639                    extraNativeRam += mi.pss;
16640                    extraNativeMemtrack += mi.memtrack;
16641                }
16642            } else {
16643                // Short form has all other details, but if we have collected RAM
16644                // from smaller native processes let's dump a summary of that.
16645                if (extraNativeRam > 0) {
16646                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16647                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16648                    shortNativeBuilder.append('\n');
16649                    extraNativeRam = 0;
16650                }
16651                appendMemInfo(fullJavaBuilder, mi);
16652            }
16653        }
16654
16655        fullJavaBuilder.append("           ");
16656        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16657        fullJavaBuilder.append(": TOTAL");
16658        if (totalMemtrack > 0) {
16659            fullJavaBuilder.append(" (");
16660            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16661            fullJavaBuilder.append(" memtrack)");
16662        } else {
16663        }
16664        fullJavaBuilder.append("\n");
16665
16666        MemInfoReader memInfo = new MemInfoReader();
16667        memInfo.readMemInfo();
16668        final long[] infos = memInfo.getRawInfo();
16669
16670        StringBuilder memInfoBuilder = new StringBuilder(1024);
16671        Debug.getMemInfo(infos);
16672        memInfoBuilder.append("  MemInfo: ");
16673        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16674        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16675        memInfoBuilder.append(stringifyKBSize(
16676                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16677        memInfoBuilder.append(stringifyKBSize(
16678                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16679        memInfoBuilder.append(stringifyKBSize(
16680                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16681        memInfoBuilder.append("           ");
16682        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16683        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16684        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16685        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16686        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16687            memInfoBuilder.append("  ZRAM: ");
16688            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16689            memInfoBuilder.append(" RAM, ");
16690            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16691            memInfoBuilder.append(" swap total, ");
16692            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16693            memInfoBuilder.append(" swap free\n");
16694        }
16695        final long[] ksm = getKsmInfo();
16696        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16697                || ksm[KSM_VOLATILE] != 0) {
16698            memInfoBuilder.append("  KSM: ");
16699            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16700            memInfoBuilder.append(" saved from shared ");
16701            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16702            memInfoBuilder.append("\n       ");
16703            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16704            memInfoBuilder.append(" unshared; ");
16705            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16706            memInfoBuilder.append(" volatile\n");
16707        }
16708        memInfoBuilder.append("  Free RAM: ");
16709        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16710                + memInfo.getFreeSizeKb()));
16711        memInfoBuilder.append("\n");
16712        memInfoBuilder.append("  Used RAM: ");
16713        memInfoBuilder.append(stringifyKBSize(
16714                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16715        memInfoBuilder.append("\n");
16716        memInfoBuilder.append("  Lost RAM: ");
16717        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16718                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16719                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16720        memInfoBuilder.append("\n");
16721        Slog.i(TAG, "Low on memory:");
16722        Slog.i(TAG, shortNativeBuilder.toString());
16723        Slog.i(TAG, fullJavaBuilder.toString());
16724        Slog.i(TAG, memInfoBuilder.toString());
16725
16726        StringBuilder dropBuilder = new StringBuilder(1024);
16727        /*
16728        StringWriter oomSw = new StringWriter();
16729        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16730        StringWriter catSw = new StringWriter();
16731        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16732        String[] emptyArgs = new String[] { };
16733        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16734        oomPw.flush();
16735        String oomString = oomSw.toString();
16736        */
16737        dropBuilder.append("Low on memory:");
16738        dropBuilder.append(stack);
16739        dropBuilder.append('\n');
16740        dropBuilder.append(fullNativeBuilder);
16741        dropBuilder.append(fullJavaBuilder);
16742        dropBuilder.append('\n');
16743        dropBuilder.append(memInfoBuilder);
16744        dropBuilder.append('\n');
16745        /*
16746        dropBuilder.append(oomString);
16747        dropBuilder.append('\n');
16748        */
16749        StringWriter catSw = new StringWriter();
16750        synchronized (ActivityManagerService.this) {
16751            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16752            String[] emptyArgs = new String[] { };
16753            catPw.println();
16754            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16755            catPw.println();
16756            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16757                    false, null).dumpLocked();
16758            catPw.println();
16759            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16760            catPw.flush();
16761        }
16762        dropBuilder.append(catSw.toString());
16763        addErrorToDropBox("lowmem", null, "system_server", null,
16764                null, tag.toString(), dropBuilder.toString(), null, null);
16765        //Slog.i(TAG, "Sent to dropbox:");
16766        //Slog.i(TAG, dropBuilder.toString());
16767        synchronized (ActivityManagerService.this) {
16768            long now = SystemClock.uptimeMillis();
16769            if (mLastMemUsageReportTime < now) {
16770                mLastMemUsageReportTime = now;
16771            }
16772        }
16773    }
16774
16775    /**
16776     * Searches array of arguments for the specified string
16777     * @param args array of argument strings
16778     * @param value value to search for
16779     * @return true if the value is contained in the array
16780     */
16781    private static boolean scanArgs(String[] args, String value) {
16782        if (args != null) {
16783            for (String arg : args) {
16784                if (value.equals(arg)) {
16785                    return true;
16786                }
16787            }
16788        }
16789        return false;
16790    }
16791
16792    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16793            ContentProviderRecord cpr, boolean always) {
16794        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16795
16796        if (!inLaunching || always) {
16797            synchronized (cpr) {
16798                cpr.launchingApp = null;
16799                cpr.notifyAll();
16800            }
16801            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16802            String names[] = cpr.info.authority.split(";");
16803            for (int j = 0; j < names.length; j++) {
16804                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16805            }
16806        }
16807
16808        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16809            ContentProviderConnection conn = cpr.connections.get(i);
16810            if (conn.waiting) {
16811                // If this connection is waiting for the provider, then we don't
16812                // need to mess with its process unless we are always removing
16813                // or for some reason the provider is not currently launching.
16814                if (inLaunching && !always) {
16815                    continue;
16816                }
16817            }
16818            ProcessRecord capp = conn.client;
16819            conn.dead = true;
16820            if (conn.stableCount > 0) {
16821                if (!capp.persistent && capp.thread != null
16822                        && capp.pid != 0
16823                        && capp.pid != MY_PID) {
16824                    capp.kill("depends on provider "
16825                            + cpr.name.flattenToShortString()
16826                            + " in dying proc " + (proc != null ? proc.processName : "??")
16827                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
16828                }
16829            } else if (capp.thread != null && conn.provider.provider != null) {
16830                try {
16831                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16832                } catch (RemoteException e) {
16833                }
16834                // In the protocol here, we don't expect the client to correctly
16835                // clean up this connection, we'll just remove it.
16836                cpr.connections.remove(i);
16837                if (conn.client.conProviders.remove(conn)) {
16838                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16839                }
16840            }
16841        }
16842
16843        if (inLaunching && always) {
16844            mLaunchingProviders.remove(cpr);
16845        }
16846        return inLaunching;
16847    }
16848
16849    /**
16850     * Main code for cleaning up a process when it has gone away.  This is
16851     * called both as a result of the process dying, or directly when stopping
16852     * a process when running in single process mode.
16853     *
16854     * @return Returns true if the given process has been restarted, so the
16855     * app that was passed in must remain on the process lists.
16856     */
16857    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16858            boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
16859        Slog.d(TAG, "cleanUpApplicationRecord -- " + app.pid);
16860        if (index >= 0) {
16861            removeLruProcessLocked(app);
16862            ProcessList.remove(app.pid);
16863        }
16864
16865        mProcessesToGc.remove(app);
16866        mPendingPssProcesses.remove(app);
16867
16868        // Dismiss any open dialogs.
16869        if (app.crashDialog != null && !app.forceCrashReport) {
16870            app.crashDialog.dismiss();
16871            app.crashDialog = null;
16872        }
16873        if (app.anrDialog != null) {
16874            app.anrDialog.dismiss();
16875            app.anrDialog = null;
16876        }
16877        if (app.waitDialog != null) {
16878            app.waitDialog.dismiss();
16879            app.waitDialog = null;
16880        }
16881
16882        app.crashing = false;
16883        app.notResponding = false;
16884
16885        app.resetPackageList(mProcessStats);
16886        app.unlinkDeathRecipient();
16887        app.makeInactive(mProcessStats);
16888        app.waitingToKill = null;
16889        app.forcingToForeground = null;
16890        updateProcessForegroundLocked(app, false, false);
16891        app.foregroundActivities = false;
16892        app.hasShownUi = false;
16893        app.treatLikeActivity = false;
16894        app.hasAboveClient = false;
16895        app.hasClientActivities = false;
16896
16897        mServices.killServicesLocked(app, allowRestart);
16898
16899        boolean restart = false;
16900
16901        // Remove published content providers.
16902        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16903            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16904            final boolean always = app.bad || !allowRestart;
16905            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16906            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16907                // We left the provider in the launching list, need to
16908                // restart it.
16909                restart = true;
16910            }
16911
16912            cpr.provider = null;
16913            cpr.proc = null;
16914        }
16915        app.pubProviders.clear();
16916
16917        // Take care of any launching providers waiting for this process.
16918        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16919            restart = true;
16920        }
16921
16922        // Unregister from connected content providers.
16923        if (!app.conProviders.isEmpty()) {
16924            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16925                ContentProviderConnection conn = app.conProviders.get(i);
16926                conn.provider.connections.remove(conn);
16927                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16928                        conn.provider.name);
16929            }
16930            app.conProviders.clear();
16931        }
16932
16933        // At this point there may be remaining entries in mLaunchingProviders
16934        // where we were the only one waiting, so they are no longer of use.
16935        // Look for these and clean up if found.
16936        // XXX Commented out for now.  Trying to figure out a way to reproduce
16937        // the actual situation to identify what is actually going on.
16938        if (false) {
16939            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16940                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16941                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16942                    synchronized (cpr) {
16943                        cpr.launchingApp = null;
16944                        cpr.notifyAll();
16945                    }
16946                }
16947            }
16948        }
16949
16950        skipCurrentReceiverLocked(app);
16951
16952        // Unregister any receivers.
16953        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16954            removeReceiverLocked(app.receivers.valueAt(i));
16955        }
16956        app.receivers.clear();
16957
16958        // If the app is undergoing backup, tell the backup manager about it
16959        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16960            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16961                    + mBackupTarget.appInfo + " died during backup");
16962            try {
16963                IBackupManager bm = IBackupManager.Stub.asInterface(
16964                        ServiceManager.getService(Context.BACKUP_SERVICE));
16965                bm.agentDisconnected(app.info.packageName);
16966            } catch (RemoteException e) {
16967                // can't happen; backup manager is local
16968            }
16969        }
16970
16971        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16972            ProcessChangeItem item = mPendingProcessChanges.get(i);
16973            if (item.pid == app.pid) {
16974                mPendingProcessChanges.remove(i);
16975                mAvailProcessChanges.add(item);
16976            }
16977        }
16978        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16979                null).sendToTarget();
16980
16981        // If the caller is restarting this app, then leave it in its
16982        // current lists and let the caller take care of it.
16983        if (restarting) {
16984            return false;
16985        }
16986
16987        if (!app.persistent || app.isolated) {
16988            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16989                    "Removing non-persistent process during cleanup: " + app);
16990            if (!replacingPid) {
16991                removeProcessNameLocked(app.processName, app.uid);
16992            }
16993            if (mHeavyWeightProcess == app) {
16994                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16995                        mHeavyWeightProcess.userId, 0));
16996                mHeavyWeightProcess = null;
16997            }
16998        } else if (!app.removed) {
16999            // This app is persistent, so we need to keep its record around.
17000            // If it is not already on the pending app list, add it there
17001            // and start a new process for it.
17002            if (mPersistentStartingProcesses.indexOf(app) < 0) {
17003                mPersistentStartingProcesses.add(app);
17004                restart = true;
17005            }
17006        }
17007        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
17008                TAG_CLEANUP, "Clean-up removing on hold: " + app);
17009        mProcessesOnHold.remove(app);
17010
17011        if (app == mHomeProcess) {
17012            mHomeProcess = null;
17013        }
17014        if (app == mPreviousProcess) {
17015            mPreviousProcess = null;
17016        }
17017
17018        if (restart && !app.isolated) {
17019            // We have components that still need to be running in the
17020            // process, so re-launch it.
17021            if (index < 0) {
17022                ProcessList.remove(app.pid);
17023            }
17024            addProcessNameLocked(app);
17025            startProcessLocked(app, "restart", app.processName);
17026            return true;
17027        } else if (app.pid > 0 && app.pid != MY_PID) {
17028            // Goodbye!
17029            boolean removed;
17030            synchronized (mPidsSelfLocked) {
17031                mPidsSelfLocked.remove(app.pid);
17032                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
17033            }
17034            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
17035            if (app.isolated) {
17036                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
17037            }
17038            app.setPid(0);
17039        }
17040        return false;
17041    }
17042
17043    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
17044        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17045            ContentProviderRecord cpr = mLaunchingProviders.get(i);
17046            if (cpr.launchingApp == app) {
17047                return true;
17048            }
17049        }
17050        return false;
17051    }
17052
17053    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
17054        // Look through the content providers we are waiting to have launched,
17055        // and if any run in this process then either schedule a restart of
17056        // the process or kill the client waiting for it if this process has
17057        // gone bad.
17058        boolean restart = false;
17059        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17060            ContentProviderRecord cpr = mLaunchingProviders.get(i);
17061            if (cpr.launchingApp == app) {
17062                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
17063                    restart = true;
17064                } else {
17065                    removeDyingProviderLocked(app, cpr, true);
17066                }
17067            }
17068        }
17069        return restart;
17070    }
17071
17072    // =========================================================
17073    // SERVICES
17074    // =========================================================
17075
17076    @Override
17077    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
17078            int flags) {
17079        enforceNotIsolatedCaller("getServices");
17080        synchronized (this) {
17081            return mServices.getRunningServiceInfoLocked(maxNum, flags);
17082        }
17083    }
17084
17085    @Override
17086    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
17087        enforceNotIsolatedCaller("getRunningServiceControlPanel");
17088        synchronized (this) {
17089            return mServices.getRunningServiceControlPanelLocked(name);
17090        }
17091    }
17092
17093    @Override
17094    public ComponentName startService(IApplicationThread caller, Intent service,
17095            String resolvedType, String callingPackage, int userId)
17096            throws TransactionTooLargeException {
17097        enforceNotIsolatedCaller("startService");
17098        // Refuse possible leaked file descriptors
17099        if (service != null && service.hasFileDescriptors() == true) {
17100            throw new IllegalArgumentException("File descriptors passed in Intent");
17101        }
17102
17103        if (callingPackage == null) {
17104            throw new IllegalArgumentException("callingPackage cannot be null");
17105        }
17106
17107        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17108                "startService: " + service + " type=" + resolvedType);
17109        synchronized(this) {
17110            final int callingPid = Binder.getCallingPid();
17111            final int callingUid = Binder.getCallingUid();
17112            final long origId = Binder.clearCallingIdentity();
17113            ComponentName res = mServices.startServiceLocked(caller, service,
17114                    resolvedType, callingPid, callingUid, callingPackage, userId);
17115            Binder.restoreCallingIdentity(origId);
17116            return res;
17117        }
17118    }
17119
17120    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
17121            String callingPackage, int userId)
17122            throws TransactionTooLargeException {
17123        synchronized(this) {
17124            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17125                    "startServiceInPackage: " + service + " type=" + resolvedType);
17126            final long origId = Binder.clearCallingIdentity();
17127            ComponentName res = mServices.startServiceLocked(null, service,
17128                    resolvedType, -1, uid, callingPackage, userId);
17129            Binder.restoreCallingIdentity(origId);
17130            return res;
17131        }
17132    }
17133
17134    @Override
17135    public int stopService(IApplicationThread caller, Intent service,
17136            String resolvedType, int userId) {
17137        enforceNotIsolatedCaller("stopService");
17138        // Refuse possible leaked file descriptors
17139        if (service != null && service.hasFileDescriptors() == true) {
17140            throw new IllegalArgumentException("File descriptors passed in Intent");
17141        }
17142
17143        synchronized(this) {
17144            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
17145        }
17146    }
17147
17148    @Override
17149    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
17150        enforceNotIsolatedCaller("peekService");
17151        // Refuse possible leaked file descriptors
17152        if (service != null && service.hasFileDescriptors() == true) {
17153            throw new IllegalArgumentException("File descriptors passed in Intent");
17154        }
17155
17156        if (callingPackage == null) {
17157            throw new IllegalArgumentException("callingPackage cannot be null");
17158        }
17159
17160        synchronized(this) {
17161            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
17162        }
17163    }
17164
17165    @Override
17166    public boolean stopServiceToken(ComponentName className, IBinder token,
17167            int startId) {
17168        synchronized(this) {
17169            return mServices.stopServiceTokenLocked(className, token, startId);
17170        }
17171    }
17172
17173    @Override
17174    public void setServiceForeground(ComponentName className, IBinder token,
17175            int id, Notification notification, int flags) {
17176        synchronized(this) {
17177            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
17178        }
17179    }
17180
17181    @Override
17182    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
17183            boolean requireFull, String name, String callerPackage) {
17184        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
17185                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
17186    }
17187
17188    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
17189            String className, int flags) {
17190        boolean result = false;
17191        // For apps that don't have pre-defined UIDs, check for permission
17192        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
17193            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17194                if (ActivityManager.checkUidPermission(
17195                        INTERACT_ACROSS_USERS,
17196                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
17197                    ComponentName comp = new ComponentName(aInfo.packageName, className);
17198                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
17199                            + " requests FLAG_SINGLE_USER, but app does not hold "
17200                            + INTERACT_ACROSS_USERS;
17201                    Slog.w(TAG, msg);
17202                    throw new SecurityException(msg);
17203                }
17204                // Permission passed
17205                result = true;
17206            }
17207        } else if ("system".equals(componentProcessName)) {
17208            result = true;
17209        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17210            // Phone app and persistent apps are allowed to export singleuser providers.
17211            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
17212                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
17213        }
17214        if (DEBUG_MU) Slog.v(TAG_MU,
17215                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
17216                + Integer.toHexString(flags) + ") = " + result);
17217        return result;
17218    }
17219
17220    /**
17221     * Checks to see if the caller is in the same app as the singleton
17222     * component, or the component is in a special app. It allows special apps
17223     * to export singleton components but prevents exporting singleton
17224     * components for regular apps.
17225     */
17226    boolean isValidSingletonCall(int callingUid, int componentUid) {
17227        int componentAppId = UserHandle.getAppId(componentUid);
17228        return UserHandle.isSameApp(callingUid, componentUid)
17229                || componentAppId == Process.SYSTEM_UID
17230                || componentAppId == Process.PHONE_UID
17231                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
17232                        == PackageManager.PERMISSION_GRANTED;
17233    }
17234
17235    public int bindService(IApplicationThread caller, IBinder token, Intent service,
17236            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
17237            int userId) throws TransactionTooLargeException {
17238        enforceNotIsolatedCaller("bindService");
17239
17240        // Refuse possible leaked file descriptors
17241        if (service != null && service.hasFileDescriptors() == true) {
17242            throw new IllegalArgumentException("File descriptors passed in Intent");
17243        }
17244
17245        if (callingPackage == null) {
17246            throw new IllegalArgumentException("callingPackage cannot be null");
17247        }
17248
17249        synchronized(this) {
17250            return mServices.bindServiceLocked(caller, token, service,
17251                    resolvedType, connection, flags, callingPackage, userId);
17252        }
17253    }
17254
17255    public boolean unbindService(IServiceConnection connection) {
17256        synchronized (this) {
17257            return mServices.unbindServiceLocked(connection);
17258        }
17259    }
17260
17261    public void publishService(IBinder token, Intent intent, IBinder service) {
17262        // Refuse possible leaked file descriptors
17263        if (intent != null && intent.hasFileDescriptors() == true) {
17264            throw new IllegalArgumentException("File descriptors passed in Intent");
17265        }
17266
17267        synchronized(this) {
17268            if (!(token instanceof ServiceRecord)) {
17269                throw new IllegalArgumentException("Invalid service token");
17270            }
17271            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17272        }
17273    }
17274
17275    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17276        // Refuse possible leaked file descriptors
17277        if (intent != null && intent.hasFileDescriptors() == true) {
17278            throw new IllegalArgumentException("File descriptors passed in Intent");
17279        }
17280
17281        synchronized(this) {
17282            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17283        }
17284    }
17285
17286    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17287        synchronized(this) {
17288            if (!(token instanceof ServiceRecord)) {
17289                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17290                throw new IllegalArgumentException("Invalid service token");
17291            }
17292            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17293        }
17294    }
17295
17296    // =========================================================
17297    // BACKUP AND RESTORE
17298    // =========================================================
17299
17300    // Cause the target app to be launched if necessary and its backup agent
17301    // instantiated.  The backup agent will invoke backupAgentCreated() on the
17302    // activity manager to announce its creation.
17303    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
17304        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
17305        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17306
17307        IPackageManager pm = AppGlobals.getPackageManager();
17308        ApplicationInfo app = null;
17309        try {
17310            app = pm.getApplicationInfo(packageName, 0, userId);
17311        } catch (RemoteException e) {
17312            // can't happen; package manager is process-local
17313        }
17314        if (app == null) {
17315            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
17316            return false;
17317        }
17318
17319        synchronized(this) {
17320            // !!! TODO: currently no check here that we're already bound
17321            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17322            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17323            synchronized (stats) {
17324                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17325            }
17326
17327            // Backup agent is now in use, its package can't be stopped.
17328            try {
17329                AppGlobals.getPackageManager().setPackageStoppedState(
17330                        app.packageName, false, UserHandle.getUserId(app.uid));
17331            } catch (RemoteException e) {
17332            } catch (IllegalArgumentException e) {
17333                Slog.w(TAG, "Failed trying to unstop package "
17334                        + app.packageName + ": " + e);
17335            }
17336
17337            BackupRecord r = new BackupRecord(ss, app, backupMode);
17338            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
17339                    ? new ComponentName(app.packageName, app.backupAgentName)
17340                    : new ComponentName("android", "FullBackupAgent");
17341            // startProcessLocked() returns existing proc's record if it's already running
17342            ProcessRecord proc = startProcessLocked(app.processName, app,
17343                    false, 0, "backup", hostingName, false, false, false);
17344            if (proc == null) {
17345                Slog.e(TAG, "Unable to start backup agent process " + r);
17346                return false;
17347            }
17348
17349            // If the app is a regular app (uid >= 10000) and not the system server or phone
17350            // process, etc, then mark it as being in full backup so that certain calls to the
17351            // process can be blocked. This is not reset to false anywhere because we kill the
17352            // process after the full backup is done and the ProcessRecord will vaporize anyway.
17353            if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
17354                proc.inFullBackup = true;
17355            }
17356            r.app = proc;
17357            mBackupTarget = r;
17358            mBackupAppName = app.packageName;
17359
17360            // Try not to kill the process during backup
17361            updateOomAdjLocked(proc);
17362
17363            // If the process is already attached, schedule the creation of the backup agent now.
17364            // If it is not yet live, this will be done when it attaches to the framework.
17365            if (proc.thread != null) {
17366                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17367                try {
17368                    proc.thread.scheduleCreateBackupAgent(app,
17369                            compatibilityInfoForPackageLocked(app), backupMode);
17370                } catch (RemoteException e) {
17371                    // Will time out on the backup manager side
17372                }
17373            } else {
17374                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17375            }
17376            // Invariants: at this point, the target app process exists and the application
17377            // is either already running or in the process of coming up.  mBackupTarget and
17378            // mBackupAppName describe the app, so that when it binds back to the AM we
17379            // know that it's scheduled for a backup-agent operation.
17380        }
17381
17382        return true;
17383    }
17384
17385    @Override
17386    public void clearPendingBackup() {
17387        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17388        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17389
17390        synchronized (this) {
17391            mBackupTarget = null;
17392            mBackupAppName = null;
17393        }
17394    }
17395
17396    // A backup agent has just come up
17397    public void backupAgentCreated(String agentPackageName, IBinder agent) {
17398        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17399                + " = " + agent);
17400
17401        synchronized(this) {
17402            if (!agentPackageName.equals(mBackupAppName)) {
17403                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17404                return;
17405            }
17406        }
17407
17408        long oldIdent = Binder.clearCallingIdentity();
17409        try {
17410            IBackupManager bm = IBackupManager.Stub.asInterface(
17411                    ServiceManager.getService(Context.BACKUP_SERVICE));
17412            bm.agentConnected(agentPackageName, agent);
17413        } catch (RemoteException e) {
17414            // can't happen; the backup manager service is local
17415        } catch (Exception e) {
17416            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17417            e.printStackTrace();
17418        } finally {
17419            Binder.restoreCallingIdentity(oldIdent);
17420        }
17421    }
17422
17423    // done with this agent
17424    public void unbindBackupAgent(ApplicationInfo appInfo) {
17425        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17426        if (appInfo == null) {
17427            Slog.w(TAG, "unbind backup agent for null app");
17428            return;
17429        }
17430
17431        synchronized(this) {
17432            try {
17433                if (mBackupAppName == null) {
17434                    Slog.w(TAG, "Unbinding backup agent with no active backup");
17435                    return;
17436                }
17437
17438                if (!mBackupAppName.equals(appInfo.packageName)) {
17439                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17440                    return;
17441                }
17442
17443                // Not backing this app up any more; reset its OOM adjustment
17444                final ProcessRecord proc = mBackupTarget.app;
17445                updateOomAdjLocked(proc);
17446
17447                // If the app crashed during backup, 'thread' will be null here
17448                if (proc.thread != null) {
17449                    try {
17450                        proc.thread.scheduleDestroyBackupAgent(appInfo,
17451                                compatibilityInfoForPackageLocked(appInfo));
17452                    } catch (Exception e) {
17453                        Slog.e(TAG, "Exception when unbinding backup agent:");
17454                        e.printStackTrace();
17455                    }
17456                }
17457            } finally {
17458                mBackupTarget = null;
17459                mBackupAppName = null;
17460            }
17461        }
17462    }
17463    // =========================================================
17464    // BROADCASTS
17465    // =========================================================
17466
17467    boolean isPendingBroadcastProcessLocked(int pid) {
17468        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17469                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17470    }
17471
17472    void skipPendingBroadcastLocked(int pid) {
17473            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17474            for (BroadcastQueue queue : mBroadcastQueues) {
17475                queue.skipPendingBroadcastLocked(pid);
17476            }
17477    }
17478
17479    // The app just attached; send any pending broadcasts that it should receive
17480    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17481        boolean didSomething = false;
17482        for (BroadcastQueue queue : mBroadcastQueues) {
17483            didSomething |= queue.sendPendingBroadcastsLocked(app);
17484        }
17485        return didSomething;
17486    }
17487
17488    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17489            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17490        enforceNotIsolatedCaller("registerReceiver");
17491        ArrayList<Intent> stickyIntents = null;
17492        ProcessRecord callerApp = null;
17493        int callingUid;
17494        int callingPid;
17495        synchronized(this) {
17496            if (caller != null) {
17497                callerApp = getRecordForAppLocked(caller);
17498                if (callerApp == null) {
17499                    throw new SecurityException(
17500                            "Unable to find app for caller " + caller
17501                            + " (pid=" + Binder.getCallingPid()
17502                            + ") when registering receiver " + receiver);
17503                }
17504                if (callerApp.info.uid != Process.SYSTEM_UID &&
17505                        !callerApp.pkgList.containsKey(callerPackage) &&
17506                        !"android".equals(callerPackage)) {
17507                    throw new SecurityException("Given caller package " + callerPackage
17508                            + " is not running in process " + callerApp);
17509                }
17510                callingUid = callerApp.info.uid;
17511                callingPid = callerApp.pid;
17512            } else {
17513                callerPackage = null;
17514                callingUid = Binder.getCallingUid();
17515                callingPid = Binder.getCallingPid();
17516            }
17517
17518            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17519                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17520
17521            Iterator<String> actions = filter.actionsIterator();
17522            if (actions == null) {
17523                ArrayList<String> noAction = new ArrayList<String>(1);
17524                noAction.add(null);
17525                actions = noAction.iterator();
17526            }
17527
17528            // Collect stickies of users
17529            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17530            while (actions.hasNext()) {
17531                String action = actions.next();
17532                for (int id : userIds) {
17533                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17534                    if (stickies != null) {
17535                        ArrayList<Intent> intents = stickies.get(action);
17536                        if (intents != null) {
17537                            if (stickyIntents == null) {
17538                                stickyIntents = new ArrayList<Intent>();
17539                            }
17540                            stickyIntents.addAll(intents);
17541                        }
17542                    }
17543                }
17544            }
17545        }
17546
17547        ArrayList<Intent> allSticky = null;
17548        if (stickyIntents != null) {
17549            final ContentResolver resolver = mContext.getContentResolver();
17550            // Look for any matching sticky broadcasts...
17551            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17552                Intent intent = stickyIntents.get(i);
17553                // If intent has scheme "content", it will need to acccess
17554                // provider that needs to lock mProviderMap in ActivityThread
17555                // and also it may need to wait application response, so we
17556                // cannot lock ActivityManagerService here.
17557                if (filter.match(resolver, intent, true, TAG) >= 0) {
17558                    if (allSticky == null) {
17559                        allSticky = new ArrayList<Intent>();
17560                    }
17561                    allSticky.add(intent);
17562                }
17563            }
17564        }
17565
17566        // The first sticky in the list is returned directly back to the client.
17567        Intent sticky = allSticky != null ? allSticky.get(0) : null;
17568        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17569        if (receiver == null) {
17570            return sticky;
17571        }
17572
17573        synchronized (this) {
17574            if (callerApp != null && (callerApp.thread == null
17575                    || callerApp.thread.asBinder() != caller.asBinder())) {
17576                // Original caller already died
17577                return null;
17578            }
17579            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17580            if (rl == null) {
17581                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17582                        userId, receiver);
17583                if (rl.app != null) {
17584                    rl.app.receivers.add(rl);
17585                } else {
17586                    try {
17587                        receiver.asBinder().linkToDeath(rl, 0);
17588                    } catch (RemoteException e) {
17589                        return sticky;
17590                    }
17591                    rl.linkedToDeath = true;
17592                }
17593                mRegisteredReceivers.put(receiver.asBinder(), rl);
17594            } else if (rl.uid != callingUid) {
17595                throw new IllegalArgumentException(
17596                        "Receiver requested to register for uid " + callingUid
17597                        + " was previously registered for uid " + rl.uid);
17598            } else if (rl.pid != callingPid) {
17599                throw new IllegalArgumentException(
17600                        "Receiver requested to register for pid " + callingPid
17601                        + " was previously registered for pid " + rl.pid);
17602            } else if (rl.userId != userId) {
17603                throw new IllegalArgumentException(
17604                        "Receiver requested to register for user " + userId
17605                        + " was previously registered for user " + rl.userId);
17606            }
17607            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17608                    permission, callingUid, userId);
17609            rl.add(bf);
17610            if (!bf.debugCheck()) {
17611                Slog.w(TAG, "==> For Dynamic broadcast");
17612            }
17613            mReceiverResolver.addFilter(bf);
17614
17615            // Enqueue broadcasts for all existing stickies that match
17616            // this filter.
17617            if (allSticky != null) {
17618                ArrayList receivers = new ArrayList();
17619                receivers.add(bf);
17620
17621                final int stickyCount = allSticky.size();
17622                for (int i = 0; i < stickyCount; i++) {
17623                    Intent intent = allSticky.get(i);
17624                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17625                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17626                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17627                            null, 0, null, null, false, true, true, -1);
17628                    queue.enqueueParallelBroadcastLocked(r);
17629                    queue.scheduleBroadcastsLocked();
17630                }
17631            }
17632
17633            return sticky;
17634        }
17635    }
17636
17637    public void unregisterReceiver(IIntentReceiver receiver) {
17638        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17639
17640        final long origId = Binder.clearCallingIdentity();
17641        try {
17642            boolean doTrim = false;
17643
17644            synchronized(this) {
17645                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17646                if (rl != null) {
17647                    final BroadcastRecord r = rl.curBroadcast;
17648                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17649                        final boolean doNext = r.queue.finishReceiverLocked(
17650                                r, r.resultCode, r.resultData, r.resultExtras,
17651                                r.resultAbort, false);
17652                        if (doNext) {
17653                            doTrim = true;
17654                            r.queue.processNextBroadcast(false);
17655                        }
17656                    }
17657
17658                    if (rl.app != null) {
17659                        rl.app.receivers.remove(rl);
17660                    }
17661                    removeReceiverLocked(rl);
17662                    if (rl.linkedToDeath) {
17663                        rl.linkedToDeath = false;
17664                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17665                    }
17666                }
17667            }
17668
17669            // If we actually concluded any broadcasts, we might now be able
17670            // to trim the recipients' apps from our working set
17671            if (doTrim) {
17672                trimApplications();
17673                return;
17674            }
17675
17676        } finally {
17677            Binder.restoreCallingIdentity(origId);
17678        }
17679    }
17680
17681    void removeReceiverLocked(ReceiverList rl) {
17682        mRegisteredReceivers.remove(rl.receiver.asBinder());
17683        for (int i = rl.size() - 1; i >= 0; i--) {
17684            mReceiverResolver.removeFilter(rl.get(i));
17685        }
17686    }
17687
17688    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17689        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17690            ProcessRecord r = mLruProcesses.get(i);
17691            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17692                try {
17693                    r.thread.dispatchPackageBroadcast(cmd, packages);
17694                } catch (RemoteException ex) {
17695                }
17696            }
17697        }
17698    }
17699
17700    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17701            int callingUid, int[] users) {
17702        // TODO: come back and remove this assumption to triage all broadcasts
17703        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17704
17705        List<ResolveInfo> receivers = null;
17706        try {
17707            HashSet<ComponentName> singleUserReceivers = null;
17708            boolean scannedFirstReceivers = false;
17709            for (int user : users) {
17710                // Skip users that have Shell restrictions, with exception of always permitted
17711                // Shell broadcasts
17712                if (callingUid == Process.SHELL_UID
17713                        && mUserController.hasUserRestriction(
17714                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17715                        && !isPermittedShellBroadcast(intent)) {
17716                    continue;
17717                }
17718                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17719                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17720                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17721                    // If this is not the system user, we need to check for
17722                    // any receivers that should be filtered out.
17723                    for (int i=0; i<newReceivers.size(); i++) {
17724                        ResolveInfo ri = newReceivers.get(i);
17725                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17726                            newReceivers.remove(i);
17727                            i--;
17728                        }
17729                    }
17730                }
17731                if (newReceivers != null && newReceivers.size() == 0) {
17732                    newReceivers = null;
17733                }
17734                if (receivers == null) {
17735                    receivers = newReceivers;
17736                } else if (newReceivers != null) {
17737                    // We need to concatenate the additional receivers
17738                    // found with what we have do far.  This would be easy,
17739                    // but we also need to de-dup any receivers that are
17740                    // singleUser.
17741                    if (!scannedFirstReceivers) {
17742                        // Collect any single user receivers we had already retrieved.
17743                        scannedFirstReceivers = true;
17744                        for (int i=0; i<receivers.size(); i++) {
17745                            ResolveInfo ri = receivers.get(i);
17746                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17747                                ComponentName cn = new ComponentName(
17748                                        ri.activityInfo.packageName, ri.activityInfo.name);
17749                                if (singleUserReceivers == null) {
17750                                    singleUserReceivers = new HashSet<ComponentName>();
17751                                }
17752                                singleUserReceivers.add(cn);
17753                            }
17754                        }
17755                    }
17756                    // Add the new results to the existing results, tracking
17757                    // and de-dupping single user receivers.
17758                    for (int i=0; i<newReceivers.size(); i++) {
17759                        ResolveInfo ri = newReceivers.get(i);
17760                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17761                            ComponentName cn = new ComponentName(
17762                                    ri.activityInfo.packageName, ri.activityInfo.name);
17763                            if (singleUserReceivers == null) {
17764                                singleUserReceivers = new HashSet<ComponentName>();
17765                            }
17766                            if (!singleUserReceivers.contains(cn)) {
17767                                singleUserReceivers.add(cn);
17768                                receivers.add(ri);
17769                            }
17770                        } else {
17771                            receivers.add(ri);
17772                        }
17773                    }
17774                }
17775            }
17776        } catch (RemoteException ex) {
17777            // pm is in same process, this will never happen.
17778        }
17779        return receivers;
17780    }
17781
17782    private boolean isPermittedShellBroadcast(Intent intent) {
17783        // remote bugreport should always be allowed to be taken
17784        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17785    }
17786
17787    private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
17788            String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
17789        final String action = intent.getAction();
17790        if (isProtectedBroadcast
17791                || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17792                || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17793                || Intent.ACTION_MEDIA_BUTTON.equals(action)
17794                || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17795                || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17796                || Intent.ACTION_MASTER_CLEAR.equals(action)
17797                || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17798                || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17799                || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17800                || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17801                || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17802            // Broadcast is either protected, or it's a public action that
17803            // we've relaxed, so it's fine for system internals to send.
17804            return;
17805        }
17806
17807        // This broadcast may be a problem...  but there are often system components that
17808        // want to send an internal broadcast to themselves, which is annoying to have to
17809        // explicitly list each action as a protected broadcast, so we will check for that
17810        // one safe case and allow it: an explicit broadcast, only being received by something
17811        // that has protected itself.
17812        if (receivers != null && receivers.size() > 0
17813                && (intent.getPackage() != null || intent.getComponent() != null)) {
17814            boolean allProtected = true;
17815            for (int i = receivers.size()-1; i >= 0; i--) {
17816                Object target = receivers.get(i);
17817                if (target instanceof ResolveInfo) {
17818                    ResolveInfo ri = (ResolveInfo)target;
17819                    if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
17820                        allProtected = false;
17821                        break;
17822                    }
17823                } else {
17824                    BroadcastFilter bf = (BroadcastFilter)target;
17825                    if (bf.requiredPermission == null) {
17826                        allProtected = false;
17827                        break;
17828                    }
17829                }
17830            }
17831            if (allProtected) {
17832                // All safe!
17833                return;
17834            }
17835        }
17836
17837        // The vast majority of broadcasts sent from system internals
17838        // should be protected to avoid security holes, so yell loudly
17839        // to ensure we examine these cases.
17840        if (callerApp != null) {
17841            Log.wtf(TAG, "Sending non-protected broadcast " + action
17842                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17843                    new Throwable());
17844        } else {
17845            Log.wtf(TAG, "Sending non-protected broadcast " + action
17846                            + " from system uid " + UserHandle.formatUid(callingUid)
17847                            + " pkg " + callerPackage,
17848                    new Throwable());
17849        }
17850    }
17851
17852    final int broadcastIntentLocked(ProcessRecord callerApp,
17853            String callerPackage, Intent intent, String resolvedType,
17854            IIntentReceiver resultTo, int resultCode, String resultData,
17855            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17856            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17857        intent = new Intent(intent);
17858
17859        // By default broadcasts do not go to stopped apps.
17860        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17861
17862        // If we have not finished booting, don't allow this to launch new processes.
17863        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17864            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17865        }
17866
17867        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17868                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17869                + " ordered=" + ordered + " userid=" + userId);
17870        if ((resultTo != null) && !ordered) {
17871            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17872        }
17873
17874        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17875                ALLOW_NON_FULL, "broadcast", callerPackage);
17876
17877        // Make sure that the user who is receiving this broadcast is running.
17878        // If not, we will just skip it. Make an exception for shutdown broadcasts
17879        // and upgrade steps.
17880
17881        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17882            if ((callingUid != Process.SYSTEM_UID
17883                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17884                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17885                Slog.w(TAG, "Skipping broadcast of " + intent
17886                        + ": user " + userId + " is stopped");
17887                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17888            }
17889        }
17890
17891        BroadcastOptions brOptions = null;
17892        if (bOptions != null) {
17893            brOptions = new BroadcastOptions(bOptions);
17894            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17895                // See if the caller is allowed to do this.  Note we are checking against
17896                // the actual real caller (not whoever provided the operation as say a
17897                // PendingIntent), because that who is actually supplied the arguments.
17898                if (checkComponentPermission(
17899                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17900                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17901                        != PackageManager.PERMISSION_GRANTED) {
17902                    String msg = "Permission Denial: " + intent.getAction()
17903                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17904                            + ", uid=" + callingUid + ")"
17905                            + " requires "
17906                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17907                    Slog.w(TAG, msg);
17908                    throw new SecurityException(msg);
17909                }
17910            }
17911        }
17912
17913        // Verify that protected broadcasts are only being sent by system code,
17914        // and that system code is only sending protected broadcasts.
17915        final String action = intent.getAction();
17916        final boolean isProtectedBroadcast;
17917        try {
17918            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17919        } catch (RemoteException e) {
17920            Slog.w(TAG, "Remote exception", e);
17921            return ActivityManager.BROADCAST_SUCCESS;
17922        }
17923
17924        final boolean isCallerSystem;
17925        switch (UserHandle.getAppId(callingUid)) {
17926            case Process.ROOT_UID:
17927            case Process.SYSTEM_UID:
17928            case Process.PHONE_UID:
17929            case Process.BLUETOOTH_UID:
17930            case Process.NFC_UID:
17931                isCallerSystem = true;
17932                break;
17933            default:
17934                isCallerSystem = (callerApp != null) && callerApp.persistent;
17935                break;
17936        }
17937
17938        // First line security check before anything else: stop non-system apps from
17939        // sending protected broadcasts.
17940        if (!isCallerSystem) {
17941            if (isProtectedBroadcast) {
17942                String msg = "Permission Denial: not allowed to send broadcast "
17943                        + action + " from pid="
17944                        + callingPid + ", uid=" + callingUid;
17945                Slog.w(TAG, msg);
17946                throw new SecurityException(msg);
17947
17948            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17949                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17950                // Special case for compatibility: we don't want apps to send this,
17951                // but historically it has not been protected and apps may be using it
17952                // to poke their own app widget.  So, instead of making it protected,
17953                // just limit it to the caller.
17954                if (callerPackage == null) {
17955                    String msg = "Permission Denial: not allowed to send broadcast "
17956                            + action + " from unknown caller.";
17957                    Slog.w(TAG, msg);
17958                    throw new SecurityException(msg);
17959                } else if (intent.getComponent() != null) {
17960                    // They are good enough to send to an explicit component...  verify
17961                    // it is being sent to the calling app.
17962                    if (!intent.getComponent().getPackageName().equals(
17963                            callerPackage)) {
17964                        String msg = "Permission Denial: not allowed to send broadcast "
17965                                + action + " to "
17966                                + intent.getComponent().getPackageName() + " from "
17967                                + callerPackage;
17968                        Slog.w(TAG, msg);
17969                        throw new SecurityException(msg);
17970                    }
17971                } else {
17972                    // Limit broadcast to their own package.
17973                    intent.setPackage(callerPackage);
17974                }
17975            }
17976        }
17977
17978        if (action != null) {
17979            switch (action) {
17980                case Intent.ACTION_UID_REMOVED:
17981                case Intent.ACTION_PACKAGE_REMOVED:
17982                case Intent.ACTION_PACKAGE_CHANGED:
17983                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17984                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17985                case Intent.ACTION_PACKAGES_SUSPENDED:
17986                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17987                    // Handle special intents: if this broadcast is from the package
17988                    // manager about a package being removed, we need to remove all of
17989                    // its activities from the history stack.
17990                    if (checkComponentPermission(
17991                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17992                            callingPid, callingUid, -1, true)
17993                            != PackageManager.PERMISSION_GRANTED) {
17994                        String msg = "Permission Denial: " + intent.getAction()
17995                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17996                                + ", uid=" + callingUid + ")"
17997                                + " requires "
17998                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17999                        Slog.w(TAG, msg);
18000                        throw new SecurityException(msg);
18001                    }
18002                    switch (action) {
18003                        case Intent.ACTION_UID_REMOVED:
18004                            final Bundle intentExtras = intent.getExtras();
18005                            final int uid = intentExtras != null
18006                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
18007                            if (uid >= 0) {
18008                                mBatteryStatsService.removeUid(uid);
18009                                mAppOpsService.uidRemoved(uid);
18010                            }
18011                            break;
18012                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18013                            // If resources are unavailable just force stop all those packages
18014                            // and flush the attribute cache as well.
18015                            String list[] =
18016                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18017                            if (list != null && list.length > 0) {
18018                                for (int i = 0; i < list.length; i++) {
18019                                    forceStopPackageLocked(list[i], -1, false, true, true,
18020                                            false, false, userId, "storage unmount");
18021                                }
18022                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18023                                sendPackageBroadcastLocked(
18024                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
18025                                        userId);
18026                            }
18027                            break;
18028                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18029                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18030                            break;
18031                        case Intent.ACTION_PACKAGE_REMOVED:
18032                        case Intent.ACTION_PACKAGE_CHANGED:
18033                            Uri data = intent.getData();
18034                            String ssp;
18035                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
18036                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
18037                                final boolean replacing =
18038                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18039                                final boolean killProcess =
18040                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
18041                                final boolean fullUninstall = removed && !replacing;
18042                                if (removed) {
18043                                    if (killProcess) {
18044                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
18045                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
18046                                                false, true, true, false, fullUninstall, userId,
18047                                                removed ? "pkg removed" : "pkg changed");
18048                                    }
18049                                    final int cmd = killProcess
18050                                            ? IApplicationThread.PACKAGE_REMOVED
18051                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
18052                                    sendPackageBroadcastLocked(cmd,
18053                                            new String[] {ssp}, userId);
18054                                    if (fullUninstall) {
18055                                        mAppOpsService.packageRemoved(
18056                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
18057
18058                                        // Remove all permissions granted from/to this package
18059                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
18060
18061                                        removeTasksByPackageNameLocked(ssp, userId);
18062
18063                                        // Hide the "unsupported display" dialog if necessary.
18064                                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18065                                                mUnsupportedDisplaySizeDialog.getPackageName())) {
18066                                            mUnsupportedDisplaySizeDialog.dismiss();
18067                                            mUnsupportedDisplaySizeDialog = null;
18068                                        }
18069                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
18070                                        mBatteryStatsService.notePackageUninstalled(ssp);
18071                                    }
18072                                } else {
18073                                    if (killProcess) {
18074                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
18075                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
18076                                                userId, ProcessList.INVALID_ADJ,
18077                                                false, true, true, false, "change " + ssp);
18078                                    }
18079                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
18080                                            intent.getStringArrayExtra(
18081                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
18082                                }
18083                            }
18084                            break;
18085                        case Intent.ACTION_PACKAGES_SUSPENDED:
18086                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
18087                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
18088                                    intent.getAction());
18089                            final String[] packageNames = intent.getStringArrayExtra(
18090                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
18091                            final int userHandle = intent.getIntExtra(
18092                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
18093
18094                            synchronized(ActivityManagerService.this) {
18095                                mRecentTasks.onPackagesSuspendedChanged(
18096                                        packageNames, suspended, userHandle);
18097                            }
18098                            break;
18099                    }
18100                    break;
18101                case Intent.ACTION_PACKAGE_REPLACED:
18102                {
18103                    final Uri data = intent.getData();
18104                    final String ssp;
18105                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18106                        final ApplicationInfo aInfo =
18107                                getPackageManagerInternalLocked().getApplicationInfo(
18108                                        ssp,
18109                                        userId);
18110                        if (aInfo == null) {
18111                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
18112                                    + " ssp=" + ssp + " data=" + data);
18113                            return ActivityManager.BROADCAST_SUCCESS;
18114                        }
18115                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
18116                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
18117                                new String[] {ssp}, userId);
18118                    }
18119                    break;
18120                }
18121                case Intent.ACTION_PACKAGE_ADDED:
18122                {
18123                    // Special case for adding a package: by default turn on compatibility mode.
18124                    Uri data = intent.getData();
18125                    String ssp;
18126                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18127                        final boolean replacing =
18128                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18129                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
18130
18131                        try {
18132                            ApplicationInfo ai = AppGlobals.getPackageManager().
18133                                    getApplicationInfo(ssp, 0, 0);
18134                            mBatteryStatsService.notePackageInstalled(ssp,
18135                                    ai != null ? ai.versionCode : 0);
18136                        } catch (RemoteException e) {
18137                        }
18138                    }
18139                    break;
18140                }
18141                case Intent.ACTION_PACKAGE_DATA_CLEARED:
18142                {
18143                    Uri data = intent.getData();
18144                    String ssp;
18145                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18146                        // Hide the "unsupported display" dialog if necessary.
18147                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18148                                mUnsupportedDisplaySizeDialog.getPackageName())) {
18149                            mUnsupportedDisplaySizeDialog.dismiss();
18150                            mUnsupportedDisplaySizeDialog = null;
18151                        }
18152                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
18153                    }
18154                    break;
18155                }
18156                case Intent.ACTION_TIMEZONE_CHANGED:
18157                    // If this is the time zone changed action, queue up a message that will reset
18158                    // the timezone of all currently running processes. This message will get
18159                    // queued up before the broadcast happens.
18160                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
18161                    break;
18162                case Intent.ACTION_TIME_CHANGED:
18163                    // If the user set the time, let all running processes know.
18164                    final int is24Hour =
18165                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
18166                                    : 0;
18167                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
18168                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18169                    synchronized (stats) {
18170                        stats.noteCurrentTimeChangedLocked();
18171                    }
18172                    break;
18173                case Intent.ACTION_CLEAR_DNS_CACHE:
18174                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
18175                    break;
18176                case Proxy.PROXY_CHANGE_ACTION:
18177                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
18178                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
18179                    break;
18180                case android.hardware.Camera.ACTION_NEW_PICTURE:
18181                case android.hardware.Camera.ACTION_NEW_VIDEO:
18182                    // These broadcasts are no longer allowed by the system, since they can
18183                    // cause significant thrashing at a crictical point (using the camera).
18184                    // Apps should use JobScehduler to monitor for media provider changes.
18185                    Slog.w(TAG, action + " no longer allowed; dropping from "
18186                            + UserHandle.formatUid(callingUid));
18187                    if (resultTo != null) {
18188                        final BroadcastQueue queue = broadcastQueueForIntent(intent);
18189                        try {
18190                            queue.performReceiveLocked(callerApp, resultTo, intent,
18191                                    Activity.RESULT_CANCELED, null, null,
18192                                    false, false, userId);
18193                        } catch (RemoteException e) {
18194                            Slog.w(TAG, "Failure ["
18195                                    + queue.mQueueName + "] sending broadcast result of "
18196                                    + intent, e);
18197
18198                        }
18199                    }
18200                    // Lie; we don't want to crash the app.
18201                    return ActivityManager.BROADCAST_SUCCESS;
18202                case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
18203                    mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
18204                    break;
18205            }
18206        }
18207
18208        // Add to the sticky list if requested.
18209        if (sticky) {
18210            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
18211                    callingPid, callingUid)
18212                    != PackageManager.PERMISSION_GRANTED) {
18213                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
18214                        + callingPid + ", uid=" + callingUid
18215                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18216                Slog.w(TAG, msg);
18217                throw new SecurityException(msg);
18218            }
18219            if (requiredPermissions != null && requiredPermissions.length > 0) {
18220                Slog.w(TAG, "Can't broadcast sticky intent " + intent
18221                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
18222                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
18223            }
18224            if (intent.getComponent() != null) {
18225                throw new SecurityException(
18226                        "Sticky broadcasts can't target a specific component");
18227            }
18228            // We use userId directly here, since the "all" target is maintained
18229            // as a separate set of sticky broadcasts.
18230            if (userId != UserHandle.USER_ALL) {
18231                // But first, if this is not a broadcast to all users, then
18232                // make sure it doesn't conflict with an existing broadcast to
18233                // all users.
18234                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
18235                        UserHandle.USER_ALL);
18236                if (stickies != null) {
18237                    ArrayList<Intent> list = stickies.get(intent.getAction());
18238                    if (list != null) {
18239                        int N = list.size();
18240                        int i;
18241                        for (i=0; i<N; i++) {
18242                            if (intent.filterEquals(list.get(i))) {
18243                                throw new IllegalArgumentException(
18244                                        "Sticky broadcast " + intent + " for user "
18245                                        + userId + " conflicts with existing global broadcast");
18246                            }
18247                        }
18248                    }
18249                }
18250            }
18251            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18252            if (stickies == null) {
18253                stickies = new ArrayMap<>();
18254                mStickyBroadcasts.put(userId, stickies);
18255            }
18256            ArrayList<Intent> list = stickies.get(intent.getAction());
18257            if (list == null) {
18258                list = new ArrayList<>();
18259                stickies.put(intent.getAction(), list);
18260            }
18261            final int stickiesCount = list.size();
18262            int i;
18263            for (i = 0; i < stickiesCount; i++) {
18264                if (intent.filterEquals(list.get(i))) {
18265                    // This sticky already exists, replace it.
18266                    list.set(i, new Intent(intent));
18267                    break;
18268                }
18269            }
18270            if (i >= stickiesCount) {
18271                list.add(new Intent(intent));
18272            }
18273        }
18274
18275        int[] users;
18276        if (userId == UserHandle.USER_ALL) {
18277            // Caller wants broadcast to go to all started users.
18278            users = mUserController.getStartedUserArrayLocked();
18279        } else {
18280            // Caller wants broadcast to go to one specific user.
18281            users = new int[] {userId};
18282        }
18283
18284        // Figure out who all will receive this broadcast.
18285        List receivers = null;
18286        List<BroadcastFilter> registeredReceivers = null;
18287        // Need to resolve the intent to interested receivers...
18288        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
18289                 == 0) {
18290            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
18291        }
18292        if (intent.getComponent() == null) {
18293            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
18294                // Query one target user at a time, excluding shell-restricted users
18295                for (int i = 0; i < users.length; i++) {
18296                    if (mUserController.hasUserRestriction(
18297                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
18298                        continue;
18299                    }
18300                    List<BroadcastFilter> registeredReceiversForUser =
18301                            mReceiverResolver.queryIntent(intent,
18302                                    resolvedType, false, users[i]);
18303                    if (registeredReceivers == null) {
18304                        registeredReceivers = registeredReceiversForUser;
18305                    } else if (registeredReceiversForUser != null) {
18306                        registeredReceivers.addAll(registeredReceiversForUser);
18307                    }
18308                }
18309            } else {
18310                registeredReceivers = mReceiverResolver.queryIntent(intent,
18311                        resolvedType, false, userId);
18312            }
18313        }
18314
18315        final boolean replacePending =
18316                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
18317
18318        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
18319                + " replacePending=" + replacePending);
18320
18321        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
18322        if (!ordered && NR > 0) {
18323            // If we are not serializing this broadcast, then send the
18324            // registered receivers separately so they don't wait for the
18325            // components to be launched.
18326            if (isCallerSystem) {
18327                checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18328                        isProtectedBroadcast, registeredReceivers);
18329            }
18330            final BroadcastQueue queue = broadcastQueueForIntent(intent);
18331            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18332                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
18333                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
18334                    resultExtras, ordered, sticky, false, userId);
18335            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
18336            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
18337            if (!replaced) {
18338                queue.enqueueParallelBroadcastLocked(r);
18339                queue.scheduleBroadcastsLocked();
18340            }
18341            registeredReceivers = null;
18342            NR = 0;
18343        }
18344
18345        // Merge into one list.
18346        int ir = 0;
18347        if (receivers != null) {
18348            // A special case for PACKAGE_ADDED: do not allow the package
18349            // being added to see this broadcast.  This prevents them from
18350            // using this as a back door to get run as soon as they are
18351            // installed.  Maybe in the future we want to have a special install
18352            // broadcast or such for apps, but we'd like to deliberately make
18353            // this decision.
18354            String skipPackages[] = null;
18355            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
18356                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
18357                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
18358                Uri data = intent.getData();
18359                if (data != null) {
18360                    String pkgName = data.getSchemeSpecificPart();
18361                    if (pkgName != null) {
18362                        skipPackages = new String[] { pkgName };
18363                    }
18364                }
18365            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18366                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18367            }
18368            if (skipPackages != null && (skipPackages.length > 0)) {
18369                for (String skipPackage : skipPackages) {
18370                    if (skipPackage != null) {
18371                        int NT = receivers.size();
18372                        for (int it=0; it<NT; it++) {
18373                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
18374                            if (curt.activityInfo.packageName.equals(skipPackage)) {
18375                                receivers.remove(it);
18376                                it--;
18377                                NT--;
18378                            }
18379                        }
18380                    }
18381                }
18382            }
18383
18384            int NT = receivers != null ? receivers.size() : 0;
18385            int it = 0;
18386            ResolveInfo curt = null;
18387            BroadcastFilter curr = null;
18388            while (it < NT && ir < NR) {
18389                if (curt == null) {
18390                    curt = (ResolveInfo)receivers.get(it);
18391                }
18392                if (curr == null) {
18393                    curr = registeredReceivers.get(ir);
18394                }
18395                if (curr.getPriority() >= curt.priority) {
18396                    // Insert this broadcast record into the final list.
18397                    receivers.add(it, curr);
18398                    ir++;
18399                    curr = null;
18400                    it++;
18401                    NT++;
18402                } else {
18403                    // Skip to the next ResolveInfo in the final list.
18404                    it++;
18405                    curt = null;
18406                }
18407            }
18408        }
18409        while (ir < NR) {
18410            if (receivers == null) {
18411                receivers = new ArrayList();
18412            }
18413            receivers.add(registeredReceivers.get(ir));
18414            ir++;
18415        }
18416
18417        if (isCallerSystem) {
18418            checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18419                    isProtectedBroadcast, receivers);
18420        }
18421
18422        if ((receivers != null && receivers.size() > 0)
18423                || resultTo != null) {
18424            BroadcastQueue queue = broadcastQueueForIntent(intent);
18425            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18426                    callerPackage, callingPid, callingUid, resolvedType,
18427                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18428                    resultData, resultExtras, ordered, sticky, false, userId);
18429
18430            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18431                    + ": prev had " + queue.mOrderedBroadcasts.size());
18432            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18433                    "Enqueueing broadcast " + r.intent.getAction());
18434
18435            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18436            if (!replaced) {
18437                queue.enqueueOrderedBroadcastLocked(r);
18438                queue.scheduleBroadcastsLocked();
18439            }
18440        } else {
18441            // There was nobody interested in the broadcast, but we still want to record
18442            // that it happened.
18443            if (intent.getComponent() == null && intent.getPackage() == null
18444                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18445                // This was an implicit broadcast... let's record it for posterity.
18446                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18447            }
18448        }
18449
18450        return ActivityManager.BROADCAST_SUCCESS;
18451    }
18452
18453    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18454            int skipCount, long dispatchTime) {
18455        final long now = SystemClock.elapsedRealtime();
18456        if (mCurBroadcastStats == null ||
18457                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18458            mLastBroadcastStats = mCurBroadcastStats;
18459            if (mLastBroadcastStats != null) {
18460                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18461                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18462            }
18463            mCurBroadcastStats = new BroadcastStats();
18464        }
18465        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18466    }
18467
18468    final Intent verifyBroadcastLocked(Intent intent) {
18469        // Refuse possible leaked file descriptors
18470        if (intent != null && intent.hasFileDescriptors() == true) {
18471            throw new IllegalArgumentException("File descriptors passed in Intent");
18472        }
18473
18474        int flags = intent.getFlags();
18475
18476        if (!mProcessesReady) {
18477            // if the caller really truly claims to know what they're doing, go
18478            // ahead and allow the broadcast without launching any receivers
18479            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18480                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18481            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18482                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18483                        + " before boot completion");
18484                throw new IllegalStateException("Cannot broadcast before boot completed");
18485            }
18486        }
18487
18488        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18489            throw new IllegalArgumentException(
18490                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18491        }
18492
18493        return intent;
18494    }
18495
18496    public final int broadcastIntent(IApplicationThread caller,
18497            Intent intent, String resolvedType, IIntentReceiver resultTo,
18498            int resultCode, String resultData, Bundle resultExtras,
18499            String[] requiredPermissions, int appOp, Bundle bOptions,
18500            boolean serialized, boolean sticky, int userId) {
18501        enforceNotIsolatedCaller("broadcastIntent");
18502        synchronized(this) {
18503            intent = verifyBroadcastLocked(intent);
18504
18505            final ProcessRecord callerApp = getRecordForAppLocked(caller);
18506            final int callingPid = Binder.getCallingPid();
18507            final int callingUid = Binder.getCallingUid();
18508            final long origId = Binder.clearCallingIdentity();
18509            int res = broadcastIntentLocked(callerApp,
18510                    callerApp != null ? callerApp.info.packageName : null,
18511                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18512                    requiredPermissions, appOp, bOptions, serialized, sticky,
18513                    callingPid, callingUid, userId);
18514            Binder.restoreCallingIdentity(origId);
18515            return res;
18516        }
18517    }
18518
18519
18520    int broadcastIntentInPackage(String packageName, int uid,
18521            Intent intent, String resolvedType, IIntentReceiver resultTo,
18522            int resultCode, String resultData, Bundle resultExtras,
18523            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18524            int userId) {
18525        synchronized(this) {
18526            intent = verifyBroadcastLocked(intent);
18527
18528            final long origId = Binder.clearCallingIdentity();
18529            String[] requiredPermissions = requiredPermission == null ? null
18530                    : new String[] {requiredPermission};
18531            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18532                    resultTo, resultCode, resultData, resultExtras,
18533                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18534                    sticky, -1, uid, userId);
18535            Binder.restoreCallingIdentity(origId);
18536            return res;
18537        }
18538    }
18539
18540    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18541        // Refuse possible leaked file descriptors
18542        if (intent != null && intent.hasFileDescriptors() == true) {
18543            throw new IllegalArgumentException("File descriptors passed in Intent");
18544        }
18545
18546        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18547                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18548
18549        synchronized(this) {
18550            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18551                    != PackageManager.PERMISSION_GRANTED) {
18552                String msg = "Permission Denial: unbroadcastIntent() from pid="
18553                        + Binder.getCallingPid()
18554                        + ", uid=" + Binder.getCallingUid()
18555                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18556                Slog.w(TAG, msg);
18557                throw new SecurityException(msg);
18558            }
18559            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18560            if (stickies != null) {
18561                ArrayList<Intent> list = stickies.get(intent.getAction());
18562                if (list != null) {
18563                    int N = list.size();
18564                    int i;
18565                    for (i=0; i<N; i++) {
18566                        if (intent.filterEquals(list.get(i))) {
18567                            list.remove(i);
18568                            break;
18569                        }
18570                    }
18571                    if (list.size() <= 0) {
18572                        stickies.remove(intent.getAction());
18573                    }
18574                }
18575                if (stickies.size() <= 0) {
18576                    mStickyBroadcasts.remove(userId);
18577                }
18578            }
18579        }
18580    }
18581
18582    void backgroundServicesFinishedLocked(int userId) {
18583        for (BroadcastQueue queue : mBroadcastQueues) {
18584            queue.backgroundServicesFinishedLocked(userId);
18585        }
18586    }
18587
18588    public void finishReceiver(IBinder who, int resultCode, String resultData,
18589            Bundle resultExtras, boolean resultAbort, int flags) {
18590        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18591
18592        // Refuse possible leaked file descriptors
18593        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18594            throw new IllegalArgumentException("File descriptors passed in Bundle");
18595        }
18596
18597        final long origId = Binder.clearCallingIdentity();
18598        try {
18599            boolean doNext = false;
18600            BroadcastRecord r;
18601
18602            synchronized(this) {
18603                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18604                        ? mFgBroadcastQueue : mBgBroadcastQueue;
18605                r = queue.getMatchingOrderedReceiver(who);
18606                if (r != null) {
18607                    doNext = r.queue.finishReceiverLocked(r, resultCode,
18608                        resultData, resultExtras, resultAbort, true);
18609                }
18610            }
18611
18612            if (doNext) {
18613                r.queue.processNextBroadcast(false);
18614            }
18615            trimApplications();
18616        } finally {
18617            Binder.restoreCallingIdentity(origId);
18618        }
18619    }
18620
18621    // =========================================================
18622    // INSTRUMENTATION
18623    // =========================================================
18624
18625    public boolean startInstrumentation(ComponentName className,
18626            String profileFile, int flags, Bundle arguments,
18627            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18628            int userId, String abiOverride) {
18629        enforceNotIsolatedCaller("startInstrumentation");
18630        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18631                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18632        // Refuse possible leaked file descriptors
18633        if (arguments != null && arguments.hasFileDescriptors()) {
18634            throw new IllegalArgumentException("File descriptors passed in Bundle");
18635        }
18636
18637        synchronized(this) {
18638            InstrumentationInfo ii = null;
18639            ApplicationInfo ai = null;
18640            try {
18641                ii = mContext.getPackageManager().getInstrumentationInfo(
18642                    className, STOCK_PM_FLAGS);
18643                ai = AppGlobals.getPackageManager().getApplicationInfo(
18644                        ii.targetPackage, STOCK_PM_FLAGS, userId);
18645            } catch (PackageManager.NameNotFoundException e) {
18646            } catch (RemoteException e) {
18647            }
18648            if (ii == null) {
18649                reportStartInstrumentationFailureLocked(watcher, className,
18650                        "Unable to find instrumentation info for: " + className);
18651                return false;
18652            }
18653            if (ai == null) {
18654                reportStartInstrumentationFailureLocked(watcher, className,
18655                        "Unable to find instrumentation target package: " + ii.targetPackage);
18656                return false;
18657            }
18658            if (!ai.hasCode()) {
18659                reportStartInstrumentationFailureLocked(watcher, className,
18660                        "Instrumentation target has no code: " + ii.targetPackage);
18661                return false;
18662            }
18663
18664            int match = mContext.getPackageManager().checkSignatures(
18665                    ii.targetPackage, ii.packageName);
18666            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18667                String msg = "Permission Denial: starting instrumentation "
18668                        + className + " from pid="
18669                        + Binder.getCallingPid()
18670                        + ", uid=" + Binder.getCallingPid()
18671                        + " not allowed because package " + ii.packageName
18672                        + " does not have a signature matching the target "
18673                        + ii.targetPackage;
18674                reportStartInstrumentationFailureLocked(watcher, className, msg);
18675                throw new SecurityException(msg);
18676            }
18677
18678            final long origId = Binder.clearCallingIdentity();
18679            // Instrumentation can kill and relaunch even persistent processes
18680            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18681                    "start instr");
18682            ProcessRecord app = addAppLocked(ai, false, abiOverride);
18683            app.instrumentationClass = className;
18684            app.instrumentationInfo = ai;
18685            app.instrumentationProfileFile = profileFile;
18686            app.instrumentationArguments = arguments;
18687            app.instrumentationWatcher = watcher;
18688            app.instrumentationUiAutomationConnection = uiAutomationConnection;
18689            app.instrumentationResultClass = className;
18690            Binder.restoreCallingIdentity(origId);
18691        }
18692
18693        return true;
18694    }
18695
18696    /**
18697     * Report errors that occur while attempting to start Instrumentation.  Always writes the
18698     * error to the logs, but if somebody is watching, send the report there too.  This enables
18699     * the "am" command to report errors with more information.
18700     *
18701     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18702     * @param cn The component name of the instrumentation.
18703     * @param report The error report.
18704     */
18705    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18706            ComponentName cn, String report) {
18707        Slog.w(TAG, report);
18708        if (watcher != null) {
18709            Bundle results = new Bundle();
18710            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18711            results.putString("Error", report);
18712            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18713        }
18714    }
18715
18716    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18717        if (app.instrumentationWatcher != null) {
18718            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18719                    app.instrumentationClass, resultCode, results);
18720        }
18721
18722        // Can't call out of the system process with a lock held, so post a message.
18723        if (app.instrumentationUiAutomationConnection != null) {
18724            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18725                    app.instrumentationUiAutomationConnection).sendToTarget();
18726        }
18727
18728        app.instrumentationWatcher = null;
18729        app.instrumentationUiAutomationConnection = null;
18730        app.instrumentationClass = null;
18731        app.instrumentationInfo = null;
18732        app.instrumentationProfileFile = null;
18733        app.instrumentationArguments = null;
18734
18735        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18736                "finished inst");
18737    }
18738
18739    public void finishInstrumentation(IApplicationThread target,
18740            int resultCode, Bundle results) {
18741        int userId = UserHandle.getCallingUserId();
18742        // Refuse possible leaked file descriptors
18743        if (results != null && results.hasFileDescriptors()) {
18744            throw new IllegalArgumentException("File descriptors passed in Intent");
18745        }
18746
18747        synchronized(this) {
18748            ProcessRecord app = getRecordForAppLocked(target);
18749            if (app == null) {
18750                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18751                return;
18752            }
18753            final long origId = Binder.clearCallingIdentity();
18754            finishInstrumentationLocked(app, resultCode, results);
18755            Binder.restoreCallingIdentity(origId);
18756        }
18757    }
18758
18759    // =========================================================
18760    // CONFIGURATION
18761    // =========================================================
18762
18763    public ConfigurationInfo getDeviceConfigurationInfo() {
18764        ConfigurationInfo config = new ConfigurationInfo();
18765        synchronized (this) {
18766            final Configuration globalConfig = getGlobalConfiguration();
18767            config.reqTouchScreen = globalConfig.touchscreen;
18768            config.reqKeyboardType = globalConfig.keyboard;
18769            config.reqNavigation = globalConfig.navigation;
18770            if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
18771                    || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
18772                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18773            }
18774            if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
18775                    && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
18776                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18777            }
18778            config.reqGlEsVersion = GL_ES_VERSION;
18779        }
18780        return config;
18781    }
18782
18783    ActivityStack getFocusedStack() {
18784        return mStackSupervisor.getFocusedStack();
18785    }
18786
18787    @Override
18788    public int getFocusedStackId() throws RemoteException {
18789        ActivityStack focusedStack = getFocusedStack();
18790        if (focusedStack != null) {
18791            return focusedStack.getStackId();
18792        }
18793        return -1;
18794    }
18795
18796    public Configuration getConfiguration() {
18797        Configuration ci;
18798        synchronized(this) {
18799            ci = new Configuration(getGlobalConfiguration());
18800            ci.userSetLocale = false;
18801        }
18802        return ci;
18803    }
18804
18805    @Override
18806    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18807        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18808        synchronized (this) {
18809            mSuppressResizeConfigChanges = suppress;
18810        }
18811    }
18812
18813    @Override
18814    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18815        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18816        if (fromStackId == HOME_STACK_ID) {
18817            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18818        }
18819        synchronized (this) {
18820            final long origId = Binder.clearCallingIdentity();
18821            try {
18822                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18823            } finally {
18824                Binder.restoreCallingIdentity(origId);
18825            }
18826        }
18827    }
18828
18829    @Override
18830    public void updatePersistentConfiguration(Configuration values) {
18831        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18832                "updatePersistentConfiguration()");
18833        enforceWriteSettingsPermission("updatePersistentConfiguration()");
18834        if (values == null) {
18835            throw new NullPointerException("Configuration must not be null");
18836        }
18837
18838        int userId = UserHandle.getCallingUserId();
18839
18840        synchronized(this) {
18841            updatePersistentConfigurationLocked(values, userId);
18842        }
18843    }
18844
18845    private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
18846        final long origId = Binder.clearCallingIdentity();
18847        try {
18848            updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
18849        } finally {
18850            Binder.restoreCallingIdentity(origId);
18851        }
18852    }
18853
18854    private void updateFontScaleIfNeeded(@UserIdInt int userId) {
18855        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18856                FONT_SCALE, 1.0f, userId);
18857        if (getGlobalConfiguration().fontScale != scaleFactor) {
18858            final Configuration configuration = mWindowManager.computeNewConfiguration();
18859            configuration.fontScale = scaleFactor;
18860            synchronized (this) {
18861                updatePersistentConfigurationLocked(configuration, userId);
18862            }
18863        }
18864    }
18865
18866    private void enforceWriteSettingsPermission(String func) {
18867        int uid = Binder.getCallingUid();
18868        if (uid == Process.ROOT_UID) {
18869            return;
18870        }
18871
18872        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18873                Settings.getPackageNameForUid(mContext, uid), false)) {
18874            return;
18875        }
18876
18877        String msg = "Permission Denial: " + func + " from pid="
18878                + Binder.getCallingPid()
18879                + ", uid=" + uid
18880                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18881        Slog.w(TAG, msg);
18882        throw new SecurityException(msg);
18883    }
18884
18885    @Override
18886    public boolean updateConfiguration(Configuration values) {
18887        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18888                "updateConfiguration()");
18889
18890        synchronized(this) {
18891            if (values == null && mWindowManager != null) {
18892                // sentinel: fetch the current configuration from the window manager
18893                values = mWindowManager.computeNewConfiguration();
18894            }
18895
18896            if (mWindowManager != null) {
18897                mProcessList.applyDisplaySize(mWindowManager);
18898            }
18899
18900            final long origId = Binder.clearCallingIdentity();
18901
18902            try {
18903                if (values != null) {
18904                    Settings.System.clearConfiguration(values);
18905                }
18906                updateConfigurationLocked(values, null, false, false /* persistent */,
18907                        UserHandle.USER_NULL, false /* deferResume */,
18908                        mTmpUpdateConfigurationResult);
18909                return mTmpUpdateConfigurationResult.changes != 0;
18910            } finally {
18911                Binder.restoreCallingIdentity(origId);
18912            }
18913        }
18914    }
18915
18916    void updateUserConfigurationLocked() {
18917        final Configuration configuration = new Configuration(getGlobalConfiguration());
18918        final int currentUserId = mUserController.getCurrentUserIdLocked();
18919        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18920                currentUserId, Settings.System.canWrite(mContext));
18921        updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
18922                false /* persistent */, currentUserId, false /* deferResume */);
18923    }
18924
18925    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18926            boolean initLocale) {
18927        return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
18928    }
18929
18930    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18931            boolean initLocale, boolean deferResume) {
18932        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18933        return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
18934                UserHandle.USER_NULL, deferResume);
18935    }
18936
18937    // To cache the list of supported system locales
18938    private String[] mSupportedSystemLocales = null;
18939
18940    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18941            boolean initLocale, boolean persistent, int userId, boolean deferResume) {
18942        return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
18943                deferResume, null /* result */);
18944    }
18945
18946    /**
18947     * Do either or both things: (1) change the current configuration, and (2)
18948     * make sure the given activity is running with the (now) current
18949     * configuration.  Returns true if the activity has been left running, or
18950     * false if <var>starting</var> is being destroyed to match the new
18951     * configuration.
18952     *
18953     * @param userId is only used when persistent parameter is set to true to persist configuration
18954     *               for that particular user
18955     */
18956    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18957            boolean initLocale, boolean persistent, int userId, boolean deferResume,
18958            UpdateConfigurationResult result) {
18959        int changes = 0;
18960        boolean kept = true;
18961
18962        if (mWindowManager != null) {
18963            mWindowManager.deferSurfaceLayout();
18964        }
18965        try {
18966            if (values != null) {
18967                changes = updateGlobalConfiguration(values, initLocale, persistent, userId,
18968                        deferResume);
18969            }
18970
18971            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
18972        } finally {
18973            if (mWindowManager != null) {
18974                mWindowManager.continueSurfaceLayout();
18975            }
18976        }
18977
18978        if (result != null) {
18979            result.changes = changes;
18980            result.activityRelaunched = !kept;
18981        }
18982        return kept;
18983    }
18984
18985    /** Update default (global) configuration and notify listeners about changes. */
18986    private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale,
18987            boolean persistent, int userId, boolean deferResume) {
18988        mTempGlobalConfig.setTo(getGlobalConfiguration());
18989        final int changes = mTempGlobalConfig.updateFrom(values);
18990        if (changes == 0) {
18991            return 0;
18992        }
18993
18994        if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18995                "Updating global configuration to: " + values);
18996
18997        EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18998
18999        if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
19000            final LocaleList locales = values.getLocales();
19001            int bestLocaleIndex = 0;
19002            if (locales.size() > 1) {
19003                if (mSupportedSystemLocales == null) {
19004                    mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
19005                }
19006                bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
19007            }
19008            SystemProperties.set("persist.sys.locale",
19009                    locales.get(bestLocaleIndex).toLanguageTag());
19010            LocaleList.setDefault(locales, bestLocaleIndex);
19011            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
19012                    locales.get(bestLocaleIndex)));
19013        }
19014
19015        mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
19016        mTempGlobalConfig.seq = mConfigurationSeq;
19017
19018        // Update stored global config and notify everyone about the change.
19019        mStackSupervisor.onConfigurationChanged(mTempGlobalConfig);
19020
19021        Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempGlobalConfig);
19022        // TODO(multi-display): Update UsageEvents#Event to include displayId.
19023        mUsageStatsService.reportConfigurationChange(mTempGlobalConfig,
19024                mUserController.getCurrentUserIdLocked());
19025
19026        // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
19027        mShowDialogs = shouldShowDialogs(mTempGlobalConfig, mInVrMode);
19028
19029        AttributeCache ac = AttributeCache.instance();
19030        if (ac != null) {
19031            ac.updateConfiguration(mTempGlobalConfig);
19032        }
19033
19034        // Make sure all resources in our process are updated right now, so that anyone who is going
19035        // to retrieve resource values after we return will be sure to get the new ones. This is
19036        // especially important during boot, where the first config change needs to guarantee all
19037        // resources have that config before following boot code is executed.
19038        mSystemThread.applyConfigurationToResources(mTempGlobalConfig);
19039
19040        // We need another copy of global config because we're scheduling some calls instead of
19041        // running them in place. We need to be sure that object we send will be handled unchanged.
19042        final Configuration configCopy = new Configuration(mTempGlobalConfig);
19043        if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
19044            Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
19045            msg.obj = configCopy;
19046            msg.arg1 = userId;
19047            mHandler.sendMessage(msg);
19048        }
19049
19050        // TODO(multi-display): Clear also on secondary display density change?
19051        final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
19052        if (isDensityChange) {
19053            // Reset the unsupported display size dialog.
19054            mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
19055
19056            killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
19057                    ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
19058        }
19059
19060        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19061            ProcessRecord app = mLruProcesses.get(i);
19062            try {
19063                if (app.thread != null) {
19064                    if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
19065                            + app.processName + " new config " + configCopy);
19066                    app.thread.scheduleConfigurationChanged(configCopy);
19067                }
19068            } catch (Exception e) {
19069            }
19070        }
19071
19072        Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
19073        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
19074                | Intent.FLAG_RECEIVER_FOREGROUND);
19075        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
19076                AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID,
19077                UserHandle.USER_ALL);
19078        if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
19079            intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
19080            intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19081            if (initLocale || !mProcessesReady) {
19082                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19083            }
19084            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
19085                    AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID,
19086                    UserHandle.USER_ALL);
19087        }
19088
19089        // Update the configuration with WM first and check if any of the stacks need to be resized
19090        // due to the configuration change. If so, resize the stacks now and do any relaunches if
19091        // necessary. This way we don't need to relaunch again afterwards in
19092        // ensureActivityConfigurationLocked().
19093        if (mWindowManager != null) {
19094            final int[] resizedStacks =
19095                    mWindowManager.setNewConfiguration(mTempGlobalConfig);
19096            if (resizedStacks != null) {
19097                for (int stackId : resizedStacks) {
19098                    resizeStackWithBoundsFromWindowManager(stackId, deferResume);
19099                }
19100            }
19101        }
19102
19103        return changes;
19104    }
19105
19106    /** Applies latest configuration and/or visibility updates if needed. */
19107    private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
19108        boolean kept = true;
19109        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
19110        // mainStack is null during startup.
19111        if (mainStack != null) {
19112            if (changes != 0 && starting == null) {
19113                // If the configuration changed, and the caller is not already
19114                // in the process of starting an activity, then find the top
19115                // activity to check if its configuration needs to change.
19116                starting = mainStack.topRunningActivityLocked();
19117            }
19118
19119            if (starting != null) {
19120                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
19121                // And we need to make sure at this point that all other activities
19122                // are made visible with the correct configuration.
19123                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
19124                        !PRESERVE_WINDOWS);
19125            }
19126        }
19127
19128        return kept;
19129    }
19130
19131    /** Helper method that requests bounds from WM and applies them to stack. */
19132    private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
19133        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
19134        mStackSupervisor.resizeStackLocked(
19135                stackId, newBounds, null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
19136                false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
19137    }
19138
19139    /**
19140     * Decide based on the configuration whether we should show the ANR,
19141     * crash, etc dialogs.  The idea is that if there is no affordance to
19142     * press the on-screen buttons, or the user experience would be more
19143     * greatly impacted than the crash itself, we shouldn't show the dialog.
19144     *
19145     * A thought: SystemUI might also want to get told about this, the Power
19146     * dialog / global actions also might want different behaviors.
19147     */
19148    private static boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
19149        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
19150                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
19151                                   && config.navigation == Configuration.NAVIGATION_NONAV);
19152        int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
19153        final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
19154                && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE)));
19155        return inputMethodExists && uiModeSupportsDialogs && !inVrMode;
19156    }
19157
19158    @Override
19159    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
19160        synchronized (this) {
19161            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
19162            if (srec != null) {
19163                return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
19164            }
19165        }
19166        return false;
19167    }
19168
19169    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
19170            Intent resultData) {
19171
19172        synchronized (this) {
19173            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
19174            if (r != null) {
19175                return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
19176            }
19177            return false;
19178        }
19179    }
19180
19181    public int getLaunchedFromUid(IBinder activityToken) {
19182        ActivityRecord srec;
19183        synchronized (this) {
19184            srec = ActivityRecord.forTokenLocked(activityToken);
19185        }
19186        if (srec == null) {
19187            return -1;
19188        }
19189        return srec.launchedFromUid;
19190    }
19191
19192    public String getLaunchedFromPackage(IBinder activityToken) {
19193        ActivityRecord srec;
19194        synchronized (this) {
19195            srec = ActivityRecord.forTokenLocked(activityToken);
19196        }
19197        if (srec == null) {
19198            return null;
19199        }
19200        return srec.launchedFromPackage;
19201    }
19202
19203    // =========================================================
19204    // LIFETIME MANAGEMENT
19205    // =========================================================
19206
19207    // Returns which broadcast queue the app is the current [or imminent] receiver
19208    // on, or 'null' if the app is not an active broadcast recipient.
19209    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
19210        BroadcastRecord r = app.curReceiver;
19211        if (r != null) {
19212            return r.queue;
19213        }
19214
19215        // It's not the current receiver, but it might be starting up to become one
19216        synchronized (this) {
19217            for (BroadcastQueue queue : mBroadcastQueues) {
19218                r = queue.mPendingBroadcast;
19219                if (r != null && r.curApp == app) {
19220                    // found it; report which queue it's in
19221                    return queue;
19222                }
19223            }
19224        }
19225
19226        return null;
19227    }
19228
19229    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
19230            int targetUid, ComponentName targetComponent, String targetProcess) {
19231        if (!mTrackingAssociations) {
19232            return null;
19233        }
19234        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19235                = mAssociations.get(targetUid);
19236        if (components == null) {
19237            components = new ArrayMap<>();
19238            mAssociations.put(targetUid, components);
19239        }
19240        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19241        if (sourceUids == null) {
19242            sourceUids = new SparseArray<>();
19243            components.put(targetComponent, sourceUids);
19244        }
19245        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19246        if (sourceProcesses == null) {
19247            sourceProcesses = new ArrayMap<>();
19248            sourceUids.put(sourceUid, sourceProcesses);
19249        }
19250        Association ass = sourceProcesses.get(sourceProcess);
19251        if (ass == null) {
19252            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
19253                    targetProcess);
19254            sourceProcesses.put(sourceProcess, ass);
19255        }
19256        ass.mCount++;
19257        ass.mNesting++;
19258        if (ass.mNesting == 1) {
19259            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
19260            ass.mLastState = sourceState;
19261        }
19262        return ass;
19263    }
19264
19265    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
19266            ComponentName targetComponent) {
19267        if (!mTrackingAssociations) {
19268            return;
19269        }
19270        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19271                = mAssociations.get(targetUid);
19272        if (components == null) {
19273            return;
19274        }
19275        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19276        if (sourceUids == null) {
19277            return;
19278        }
19279        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19280        if (sourceProcesses == null) {
19281            return;
19282        }
19283        Association ass = sourceProcesses.get(sourceProcess);
19284        if (ass == null || ass.mNesting <= 0) {
19285            return;
19286        }
19287        ass.mNesting--;
19288        if (ass.mNesting == 0) {
19289            long uptime = SystemClock.uptimeMillis();
19290            ass.mTime += uptime - ass.mStartTime;
19291            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19292                    += uptime - ass.mLastStateUptime;
19293            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
19294        }
19295    }
19296
19297    private void noteUidProcessState(final int uid, final int state) {
19298        mBatteryStatsService.noteUidProcessState(uid, state);
19299        if (mTrackingAssociations) {
19300            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
19301                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
19302                        = mAssociations.valueAt(i1);
19303                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
19304                    SparseArray<ArrayMap<String, Association>> sourceUids
19305                            = targetComponents.valueAt(i2);
19306                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
19307                    if (sourceProcesses != null) {
19308                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
19309                            Association ass = sourceProcesses.valueAt(i4);
19310                            if (ass.mNesting >= 1) {
19311                                // currently associated
19312                                long uptime = SystemClock.uptimeMillis();
19313                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19314                                        += uptime - ass.mLastStateUptime;
19315                                ass.mLastState = state;
19316                                ass.mLastStateUptime = uptime;
19317                            }
19318                        }
19319                    }
19320                }
19321            }
19322        }
19323    }
19324
19325    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
19326            boolean doingAll, long now) {
19327        if (mAdjSeq == app.adjSeq) {
19328            // This adjustment has already been computed.
19329            return app.curRawAdj;
19330        }
19331
19332        if (app.thread == null) {
19333            app.adjSeq = mAdjSeq;
19334            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19335            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19336            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
19337        }
19338
19339        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
19340        app.adjSource = null;
19341        app.adjTarget = null;
19342        app.empty = false;
19343        app.cached = false;
19344
19345        final int activitiesSize = app.activities.size();
19346
19347        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19348            // The max adjustment doesn't allow this app to be anything
19349            // below foreground, so it is not worth doing work for it.
19350            app.adjType = "fixed";
19351            app.adjSeq = mAdjSeq;
19352            app.curRawAdj = app.maxAdj;
19353            app.foregroundActivities = false;
19354            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19355            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
19356            // System processes can do UI, and when they do we want to have
19357            // them trim their memory after the user leaves the UI.  To
19358            // facilitate this, here we need to determine whether or not it
19359            // is currently showing UI.
19360            app.systemNoUi = true;
19361            if (app == TOP_APP) {
19362                app.systemNoUi = false;
19363                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19364                app.adjType = "pers-top-activity";
19365            } else if (app.hasTopUi) {
19366                app.systemNoUi = false;
19367                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19368                app.adjType = "pers-top-ui";
19369            } else if (activitiesSize > 0) {
19370                for (int j = 0; j < activitiesSize; j++) {
19371                    final ActivityRecord r = app.activities.get(j);
19372                    if (r.visible) {
19373                        app.systemNoUi = false;
19374                    }
19375                }
19376            }
19377            if (!app.systemNoUi) {
19378                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
19379            }
19380            return (app.curAdj=app.maxAdj);
19381        }
19382
19383        app.systemNoUi = false;
19384
19385        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
19386
19387        // Determine the importance of the process, starting with most
19388        // important to least, and assign an appropriate OOM adjustment.
19389        int adj;
19390        int schedGroup;
19391        int procState;
19392        boolean foregroundActivities = false;
19393        BroadcastQueue queue;
19394        if (app == TOP_APP) {
19395            // The last app on the list is the foreground app.
19396            adj = ProcessList.FOREGROUND_APP_ADJ;
19397            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19398            app.adjType = "top-activity";
19399            foregroundActivities = true;
19400            procState = PROCESS_STATE_CUR_TOP;
19401        } else if (app.instrumentationClass != null) {
19402            // Don't want to kill running instrumentation.
19403            adj = ProcessList.FOREGROUND_APP_ADJ;
19404            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19405            app.adjType = "instrumentation";
19406            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19407        } else if ((queue = isReceivingBroadcast(app)) != null) {
19408            // An app that is currently receiving a broadcast also
19409            // counts as being in the foreground for OOM killer purposes.
19410            // It's placed in a sched group based on the nature of the
19411            // broadcast as reflected by which queue it's active in.
19412            adj = ProcessList.FOREGROUND_APP_ADJ;
19413            schedGroup = (queue == mFgBroadcastQueue)
19414                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19415            app.adjType = "broadcast";
19416            procState = ActivityManager.PROCESS_STATE_RECEIVER;
19417        } else if (app.executingServices.size() > 0) {
19418            // An app that is currently executing a service callback also
19419            // counts as being in the foreground.
19420            adj = ProcessList.FOREGROUND_APP_ADJ;
19421            schedGroup = app.execServicesFg ?
19422                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19423            app.adjType = "exec-service";
19424            procState = ActivityManager.PROCESS_STATE_SERVICE;
19425            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
19426        } else {
19427            // As far as we know the process is empty.  We may change our mind later.
19428            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19429            // At this point we don't actually know the adjustment.  Use the cached adj
19430            // value that the caller wants us to.
19431            adj = cachedAdj;
19432            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19433            app.cached = true;
19434            app.empty = true;
19435            app.adjType = "cch-empty";
19436        }
19437
19438        // Examine all activities if not already foreground.
19439        if (!foregroundActivities && activitiesSize > 0) {
19440            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
19441            for (int j = 0; j < activitiesSize; j++) {
19442                final ActivityRecord r = app.activities.get(j);
19443                if (r.app != app) {
19444                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
19445                            + " instead of expected " + app);
19446                    if (r.app == null || (r.app.uid == app.uid)) {
19447                        // Only fix things up when they look sane
19448                        r.app = app;
19449                    } else {
19450                        continue;
19451                    }
19452                }
19453                if (r.visible) {
19454                    // App has a visible activity; only upgrade adjustment.
19455                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19456                        adj = ProcessList.VISIBLE_APP_ADJ;
19457                        app.adjType = "visible";
19458                    }
19459                    if (procState > PROCESS_STATE_CUR_TOP) {
19460                        procState = PROCESS_STATE_CUR_TOP;
19461                    }
19462                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19463                    app.cached = false;
19464                    app.empty = false;
19465                    foregroundActivities = true;
19466                    if (r.task != null && minLayer > 0) {
19467                        final int layer = r.task.mLayerRank;
19468                        if (layer >= 0 && minLayer > layer) {
19469                            minLayer = layer;
19470                        }
19471                    }
19472                    break;
19473                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19474                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19475                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19476                        app.adjType = "pausing";
19477                    }
19478                    if (procState > PROCESS_STATE_CUR_TOP) {
19479                        procState = PROCESS_STATE_CUR_TOP;
19480                    }
19481                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19482                    app.cached = false;
19483                    app.empty = false;
19484                    foregroundActivities = true;
19485                } else if (r.state == ActivityState.STOPPING) {
19486                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19487                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19488                        app.adjType = "stopping";
19489                    }
19490                    // For the process state, we will at this point consider the
19491                    // process to be cached.  It will be cached either as an activity
19492                    // or empty depending on whether the activity is finishing.  We do
19493                    // this so that we can treat the process as cached for purposes of
19494                    // memory trimming (determing current memory level, trim command to
19495                    // send to process) since there can be an arbitrary number of stopping
19496                    // processes and they should soon all go into the cached state.
19497                    if (!r.finishing) {
19498                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19499                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19500                        }
19501                    }
19502                    app.cached = false;
19503                    app.empty = false;
19504                    foregroundActivities = true;
19505                } else {
19506                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19507                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19508                        app.adjType = "cch-act";
19509                    }
19510                }
19511            }
19512            if (adj == ProcessList.VISIBLE_APP_ADJ) {
19513                adj += minLayer;
19514            }
19515        }
19516
19517        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19518                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19519            if (app.foregroundServices) {
19520                // The user is aware of this app, so make it visible.
19521                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19522                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19523                app.cached = false;
19524                app.adjType = "fg-service";
19525                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19526            } else if (app.forcingToForeground != null) {
19527                // The user is aware of this app, so make it visible.
19528                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19529                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19530                app.cached = false;
19531                app.adjType = "force-fg";
19532                app.adjSource = app.forcingToForeground;
19533                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19534            }
19535        }
19536
19537        if (app == mHeavyWeightProcess) {
19538            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19539                // We don't want to kill the current heavy-weight process.
19540                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19541                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19542                app.cached = false;
19543                app.adjType = "heavy";
19544            }
19545            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19546                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19547            }
19548        }
19549
19550        if (app == mHomeProcess) {
19551            if (adj > ProcessList.HOME_APP_ADJ) {
19552                // This process is hosting what we currently consider to be the
19553                // home app, so we don't want to let it go into the background.
19554                adj = ProcessList.HOME_APP_ADJ;
19555                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19556                app.cached = false;
19557                app.adjType = "home";
19558            }
19559            if (procState > ActivityManager.PROCESS_STATE_HOME) {
19560                procState = ActivityManager.PROCESS_STATE_HOME;
19561            }
19562        }
19563
19564        if (app == mPreviousProcess && app.activities.size() > 0) {
19565            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19566                // This was the previous process that showed UI to the user.
19567                // We want to try to keep it around more aggressively, to give
19568                // a good experience around switching between two apps.
19569                adj = ProcessList.PREVIOUS_APP_ADJ;
19570                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19571                app.cached = false;
19572                app.adjType = "previous";
19573            }
19574            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19575                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19576            }
19577        }
19578
19579        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19580                + " reason=" + app.adjType);
19581
19582        // By default, we use the computed adjustment.  It may be changed if
19583        // there are applications dependent on our services or providers, but
19584        // this gives us a baseline and makes sure we don't get into an
19585        // infinite recursion.
19586        app.adjSeq = mAdjSeq;
19587        app.curRawAdj = adj;
19588        app.hasStartedServices = false;
19589
19590        if (mBackupTarget != null && app == mBackupTarget.app) {
19591            // If possible we want to avoid killing apps while they're being backed up
19592            if (adj > ProcessList.BACKUP_APP_ADJ) {
19593                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19594                adj = ProcessList.BACKUP_APP_ADJ;
19595                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19596                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19597                }
19598                app.adjType = "backup";
19599                app.cached = false;
19600            }
19601            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19602                procState = ActivityManager.PROCESS_STATE_BACKUP;
19603            }
19604        }
19605
19606        boolean mayBeTop = false;
19607
19608        for (int is = app.services.size()-1;
19609                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19610                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19611                        || procState > ActivityManager.PROCESS_STATE_TOP);
19612                is--) {
19613            ServiceRecord s = app.services.valueAt(is);
19614            if (s.startRequested) {
19615                app.hasStartedServices = true;
19616                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19617                    procState = ActivityManager.PROCESS_STATE_SERVICE;
19618                }
19619                if (app.hasShownUi && app != mHomeProcess) {
19620                    // If this process has shown some UI, let it immediately
19621                    // go to the LRU list because it may be pretty heavy with
19622                    // UI stuff.  We'll tag it with a label just to help
19623                    // debug and understand what is going on.
19624                    if (adj > ProcessList.SERVICE_ADJ) {
19625                        app.adjType = "cch-started-ui-services";
19626                    }
19627                } else {
19628                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19629                        // This service has seen some activity within
19630                        // recent memory, so we will keep its process ahead
19631                        // of the background processes.
19632                        if (adj > ProcessList.SERVICE_ADJ) {
19633                            adj = ProcessList.SERVICE_ADJ;
19634                            app.adjType = "started-services";
19635                            app.cached = false;
19636                        }
19637                    }
19638                    // If we have let the service slide into the background
19639                    // state, still have some text describing what it is doing
19640                    // even though the service no longer has an impact.
19641                    if (adj > ProcessList.SERVICE_ADJ) {
19642                        app.adjType = "cch-started-services";
19643                    }
19644                }
19645            }
19646
19647            for (int conni = s.connections.size()-1;
19648                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19649                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19650                            || procState > ActivityManager.PROCESS_STATE_TOP);
19651                    conni--) {
19652                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19653                for (int i = 0;
19654                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19655                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19656                                || procState > ActivityManager.PROCESS_STATE_TOP);
19657                        i++) {
19658                    // XXX should compute this based on the max of
19659                    // all connected clients.
19660                    ConnectionRecord cr = clist.get(i);
19661                    if (cr.binding.client == app) {
19662                        // Binding to ourself is not interesting.
19663                        continue;
19664                    }
19665
19666                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19667                        ProcessRecord client = cr.binding.client;
19668                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
19669                                TOP_APP, doingAll, now);
19670                        int clientProcState = client.curProcState;
19671                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19672                            // If the other app is cached for any reason, for purposes here
19673                            // we are going to consider it empty.  The specific cached state
19674                            // doesn't propagate except under certain conditions.
19675                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19676                        }
19677                        String adjType = null;
19678                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19679                            // Not doing bind OOM management, so treat
19680                            // this guy more like a started service.
19681                            if (app.hasShownUi && app != mHomeProcess) {
19682                                // If this process has shown some UI, let it immediately
19683                                // go to the LRU list because it may be pretty heavy with
19684                                // UI stuff.  We'll tag it with a label just to help
19685                                // debug and understand what is going on.
19686                                if (adj > clientAdj) {
19687                                    adjType = "cch-bound-ui-services";
19688                                }
19689                                app.cached = false;
19690                                clientAdj = adj;
19691                                clientProcState = procState;
19692                            } else {
19693                                if (now >= (s.lastActivity
19694                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19695                                    // This service has not seen activity within
19696                                    // recent memory, so allow it to drop to the
19697                                    // LRU list if there is no other reason to keep
19698                                    // it around.  We'll also tag it with a label just
19699                                    // to help debug and undertand what is going on.
19700                                    if (adj > clientAdj) {
19701                                        adjType = "cch-bound-services";
19702                                    }
19703                                    clientAdj = adj;
19704                                }
19705                            }
19706                        }
19707                        if (adj > clientAdj) {
19708                            // If this process has recently shown UI, and
19709                            // the process that is binding to it is less
19710                            // important than being visible, then we don't
19711                            // care about the binding as much as we care
19712                            // about letting this process get into the LRU
19713                            // list to be killed and restarted if needed for
19714                            // memory.
19715                            if (app.hasShownUi && app != mHomeProcess
19716                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19717                                adjType = "cch-bound-ui-services";
19718                            } else {
19719                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19720                                        |Context.BIND_IMPORTANT)) != 0) {
19721                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19722                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19723                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19724                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19725                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19726                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19727                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19728                                    adj = clientAdj;
19729                                } else {
19730                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19731                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19732                                    }
19733                                }
19734                                if (!client.cached) {
19735                                    app.cached = false;
19736                                }
19737                                adjType = "service";
19738                            }
19739                        }
19740                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19741                            // This will treat important bound services identically to
19742                            // the top app, which may behave differently than generic
19743                            // foreground work.
19744                            if (client.curSchedGroup > schedGroup) {
19745                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19746                                    schedGroup = client.curSchedGroup;
19747                                } else {
19748                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19749                                }
19750                            }
19751                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19752                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19753                                    // Special handling of clients who are in the top state.
19754                                    // We *may* want to consider this process to be in the
19755                                    // top state as well, but only if there is not another
19756                                    // reason for it to be running.  Being on the top is a
19757                                    // special state, meaning you are specifically running
19758                                    // for the current top app.  If the process is already
19759                                    // running in the background for some other reason, it
19760                                    // is more important to continue considering it to be
19761                                    // in the background state.
19762                                    mayBeTop = true;
19763                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19764                                } else {
19765                                    // Special handling for above-top states (persistent
19766                                    // processes).  These should not bring the current process
19767                                    // into the top state, since they are not on top.  Instead
19768                                    // give them the best state after that.
19769                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19770                                        clientProcState =
19771                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19772                                    } else if (mWakefulness
19773                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19774                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19775                                                    != 0) {
19776                                        clientProcState =
19777                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19778                                    } else {
19779                                        clientProcState =
19780                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19781                                    }
19782                                }
19783                            }
19784                        } else {
19785                            if (clientProcState <
19786                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19787                                clientProcState =
19788                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19789                            }
19790                        }
19791                        if (procState > clientProcState) {
19792                            procState = clientProcState;
19793                        }
19794                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19795                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19796                            app.pendingUiClean = true;
19797                        }
19798                        if (adjType != null) {
19799                            app.adjType = adjType;
19800                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19801                                    .REASON_SERVICE_IN_USE;
19802                            app.adjSource = cr.binding.client;
19803                            app.adjSourceProcState = clientProcState;
19804                            app.adjTarget = s.name;
19805                        }
19806                    }
19807                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19808                        app.treatLikeActivity = true;
19809                    }
19810                    final ActivityRecord a = cr.activity;
19811                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19812                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19813                            (a.visible || a.state == ActivityState.RESUMED ||
19814                             a.state == ActivityState.PAUSING)) {
19815                            adj = ProcessList.FOREGROUND_APP_ADJ;
19816                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19817                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19818                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
19819                                } else {
19820                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19821                                }
19822                            }
19823                            app.cached = false;
19824                            app.adjType = "service";
19825                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19826                                    .REASON_SERVICE_IN_USE;
19827                            app.adjSource = a;
19828                            app.adjSourceProcState = procState;
19829                            app.adjTarget = s.name;
19830                        }
19831                    }
19832                }
19833            }
19834        }
19835
19836        for (int provi = app.pubProviders.size()-1;
19837                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19838                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19839                        || procState > ActivityManager.PROCESS_STATE_TOP);
19840                provi--) {
19841            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19842            for (int i = cpr.connections.size()-1;
19843                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19844                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19845                            || procState > ActivityManager.PROCESS_STATE_TOP);
19846                    i--) {
19847                ContentProviderConnection conn = cpr.connections.get(i);
19848                ProcessRecord client = conn.client;
19849                if (client == app) {
19850                    // Being our own client is not interesting.
19851                    continue;
19852                }
19853                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19854                int clientProcState = client.curProcState;
19855                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19856                    // If the other app is cached for any reason, for purposes here
19857                    // we are going to consider it empty.
19858                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19859                }
19860                if (adj > clientAdj) {
19861                    if (app.hasShownUi && app != mHomeProcess
19862                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19863                        app.adjType = "cch-ui-provider";
19864                    } else {
19865                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19866                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19867                        app.adjType = "provider";
19868                    }
19869                    app.cached &= client.cached;
19870                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19871                            .REASON_PROVIDER_IN_USE;
19872                    app.adjSource = client;
19873                    app.adjSourceProcState = clientProcState;
19874                    app.adjTarget = cpr.name;
19875                }
19876                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19877                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19878                        // Special handling of clients who are in the top state.
19879                        // We *may* want to consider this process to be in the
19880                        // top state as well, but only if there is not another
19881                        // reason for it to be running.  Being on the top is a
19882                        // special state, meaning you are specifically running
19883                        // for the current top app.  If the process is already
19884                        // running in the background for some other reason, it
19885                        // is more important to continue considering it to be
19886                        // in the background state.
19887                        mayBeTop = true;
19888                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19889                    } else {
19890                        // Special handling for above-top states (persistent
19891                        // processes).  These should not bring the current process
19892                        // into the top state, since they are not on top.  Instead
19893                        // give them the best state after that.
19894                        clientProcState =
19895                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19896                    }
19897                }
19898                if (procState > clientProcState) {
19899                    procState = clientProcState;
19900                }
19901                if (client.curSchedGroup > schedGroup) {
19902                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19903                }
19904            }
19905            // If the provider has external (non-framework) process
19906            // dependencies, ensure that its adjustment is at least
19907            // FOREGROUND_APP_ADJ.
19908            if (cpr.hasExternalProcessHandles()) {
19909                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19910                    adj = ProcessList.FOREGROUND_APP_ADJ;
19911                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19912                    app.cached = false;
19913                    app.adjType = "provider";
19914                    app.adjTarget = cpr.name;
19915                }
19916                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19917                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19918                }
19919            }
19920        }
19921
19922        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19923            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19924                adj = ProcessList.PREVIOUS_APP_ADJ;
19925                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19926                app.cached = false;
19927                app.adjType = "provider";
19928            }
19929            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19930                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19931            }
19932        }
19933
19934        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19935            // A client of one of our services or providers is in the top state.  We
19936            // *may* want to be in the top state, but not if we are already running in
19937            // the background for some other reason.  For the decision here, we are going
19938            // to pick out a few specific states that we want to remain in when a client
19939            // is top (states that tend to be longer-term) and otherwise allow it to go
19940            // to the top state.
19941            switch (procState) {
19942                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19943                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19944                case ActivityManager.PROCESS_STATE_SERVICE:
19945                    // These all are longer-term states, so pull them up to the top
19946                    // of the background states, but not all the way to the top state.
19947                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19948                    break;
19949                default:
19950                    // Otherwise, top is a better choice, so take it.
19951                    procState = ActivityManager.PROCESS_STATE_TOP;
19952                    break;
19953            }
19954        }
19955
19956        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19957            if (app.hasClientActivities) {
19958                // This is a cached process, but with client activities.  Mark it so.
19959                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19960                app.adjType = "cch-client-act";
19961            } else if (app.treatLikeActivity) {
19962                // This is a cached process, but somebody wants us to treat it like it has
19963                // an activity, okay!
19964                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19965                app.adjType = "cch-as-act";
19966            }
19967        }
19968
19969        if (adj == ProcessList.SERVICE_ADJ) {
19970            if (doingAll) {
19971                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19972                mNewNumServiceProcs++;
19973                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19974                if (!app.serviceb) {
19975                    // This service isn't far enough down on the LRU list to
19976                    // normally be a B service, but if we are low on RAM and it
19977                    // is large we want to force it down since we would prefer to
19978                    // keep launcher over it.
19979                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19980                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19981                        app.serviceHighRam = true;
19982                        app.serviceb = true;
19983                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19984                    } else {
19985                        mNewNumAServiceProcs++;
19986                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19987                    }
19988                } else {
19989                    app.serviceHighRam = false;
19990                }
19991            }
19992            if (app.serviceb) {
19993                adj = ProcessList.SERVICE_B_ADJ;
19994            }
19995        }
19996
19997        app.curRawAdj = adj;
19998
19999        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
20000        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
20001        if (adj > app.maxAdj) {
20002            adj = app.maxAdj;
20003            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
20004                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20005            }
20006        }
20007
20008        // Do final modification to adj.  Everything we do between here and applying
20009        // the final setAdj must be done in this function, because we will also use
20010        // it when computing the final cached adj later.  Note that we don't need to
20011        // worry about this for max adj above, since max adj will always be used to
20012        // keep it out of the cached vaues.
20013        app.curAdj = app.modifyRawOomAdj(adj);
20014        app.curSchedGroup = schedGroup;
20015        app.curProcState = procState;
20016        app.foregroundActivities = foregroundActivities;
20017
20018        return app.curRawAdj;
20019    }
20020
20021    /**
20022     * Record new PSS sample for a process.
20023     */
20024    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
20025            long now) {
20026        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
20027                swapPss * 1024);
20028        proc.lastPssTime = now;
20029        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
20030        if (DEBUG_PSS) Slog.d(TAG_PSS,
20031                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
20032                + " state=" + ProcessList.makeProcStateString(procState));
20033        if (proc.initialIdlePss == 0) {
20034            proc.initialIdlePss = pss;
20035        }
20036        proc.lastPss = pss;
20037        proc.lastSwapPss = swapPss;
20038        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
20039            proc.lastCachedPss = pss;
20040            proc.lastCachedSwapPss = swapPss;
20041        }
20042
20043        final SparseArray<Pair<Long, String>> watchUids
20044                = mMemWatchProcesses.getMap().get(proc.processName);
20045        Long check = null;
20046        if (watchUids != null) {
20047            Pair<Long, String> val = watchUids.get(proc.uid);
20048            if (val == null) {
20049                val = watchUids.get(0);
20050            }
20051            if (val != null) {
20052                check = val.first;
20053            }
20054        }
20055        if (check != null) {
20056            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
20057                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20058                if (!isDebuggable) {
20059                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
20060                        isDebuggable = true;
20061                    }
20062                }
20063                if (isDebuggable) {
20064                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
20065                    final ProcessRecord myProc = proc;
20066                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
20067                    mMemWatchDumpProcName = proc.processName;
20068                    mMemWatchDumpFile = heapdumpFile.toString();
20069                    mMemWatchDumpPid = proc.pid;
20070                    mMemWatchDumpUid = proc.uid;
20071                    BackgroundThread.getHandler().post(new Runnable() {
20072                        @Override
20073                        public void run() {
20074                            revokeUriPermission(ActivityThread.currentActivityThread()
20075                                            .getApplicationThread(),
20076                                    DumpHeapActivity.JAVA_URI,
20077                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
20078                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
20079                                    UserHandle.myUserId());
20080                            ParcelFileDescriptor fd = null;
20081                            try {
20082                                heapdumpFile.delete();
20083                                fd = ParcelFileDescriptor.open(heapdumpFile,
20084                                        ParcelFileDescriptor.MODE_CREATE |
20085                                                ParcelFileDescriptor.MODE_TRUNCATE |
20086                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
20087                                                ParcelFileDescriptor.MODE_APPEND);
20088                                IApplicationThread thread = myProc.thread;
20089                                if (thread != null) {
20090                                    try {
20091                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
20092                                                "Requesting dump heap from "
20093                                                + myProc + " to " + heapdumpFile);
20094                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
20095                                    } catch (RemoteException e) {
20096                                    }
20097                                }
20098                            } catch (FileNotFoundException e) {
20099                                e.printStackTrace();
20100                            } finally {
20101                                if (fd != null) {
20102                                    try {
20103                                        fd.close();
20104                                    } catch (IOException e) {
20105                                    }
20106                                }
20107                            }
20108                        }
20109                    });
20110                } else {
20111                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
20112                            + ", but debugging not enabled");
20113                }
20114            }
20115        }
20116    }
20117
20118    /**
20119     * Schedule PSS collection of a process.
20120     */
20121    void requestPssLocked(ProcessRecord proc, int procState) {
20122        if (mPendingPssProcesses.contains(proc)) {
20123            return;
20124        }
20125        if (mPendingPssProcesses.size() == 0) {
20126            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20127        }
20128        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
20129        proc.pssProcState = procState;
20130        mPendingPssProcesses.add(proc);
20131    }
20132
20133    /**
20134     * Schedule PSS collection of all processes.
20135     */
20136    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
20137        if (!always) {
20138            if (now < (mLastFullPssTime +
20139                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
20140                return;
20141            }
20142        }
20143        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
20144        mLastFullPssTime = now;
20145        mFullPssPending = true;
20146        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
20147        mPendingPssProcesses.clear();
20148        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20149            ProcessRecord app = mLruProcesses.get(i);
20150            if (app.thread == null
20151                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
20152                continue;
20153            }
20154            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
20155                app.pssProcState = app.setProcState;
20156                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20157                        mTestPssMode, isSleepingLocked(), now);
20158                mPendingPssProcesses.add(app);
20159            }
20160        }
20161        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20162    }
20163
20164    public void setTestPssMode(boolean enabled) {
20165        synchronized (this) {
20166            mTestPssMode = enabled;
20167            if (enabled) {
20168                // Whenever we enable the mode, we want to take a snapshot all of current
20169                // process mem use.
20170                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
20171            }
20172        }
20173    }
20174
20175    /**
20176     * Ask a given process to GC right now.
20177     */
20178    final void performAppGcLocked(ProcessRecord app) {
20179        try {
20180            app.lastRequestedGc = SystemClock.uptimeMillis();
20181            if (app.thread != null) {
20182                if (app.reportLowMemory) {
20183                    app.reportLowMemory = false;
20184                    app.thread.scheduleLowMemory();
20185                } else {
20186                    app.thread.processInBackground();
20187                }
20188            }
20189        } catch (Exception e) {
20190            // whatever.
20191        }
20192    }
20193
20194    /**
20195     * Returns true if things are idle enough to perform GCs.
20196     */
20197    private final boolean canGcNowLocked() {
20198        boolean processingBroadcasts = false;
20199        for (BroadcastQueue q : mBroadcastQueues) {
20200            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
20201                processingBroadcasts = true;
20202            }
20203        }
20204        return !processingBroadcasts
20205                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
20206    }
20207
20208    /**
20209     * Perform GCs on all processes that are waiting for it, but only
20210     * if things are idle.
20211     */
20212    final void performAppGcsLocked() {
20213        final int N = mProcessesToGc.size();
20214        if (N <= 0) {
20215            return;
20216        }
20217        if (canGcNowLocked()) {
20218            while (mProcessesToGc.size() > 0) {
20219                ProcessRecord proc = mProcessesToGc.remove(0);
20220                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
20221                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
20222                            <= SystemClock.uptimeMillis()) {
20223                        // To avoid spamming the system, we will GC processes one
20224                        // at a time, waiting a few seconds between each.
20225                        performAppGcLocked(proc);
20226                        scheduleAppGcsLocked();
20227                        return;
20228                    } else {
20229                        // It hasn't been long enough since we last GCed this
20230                        // process...  put it in the list to wait for its time.
20231                        addProcessToGcListLocked(proc);
20232                        break;
20233                    }
20234                }
20235            }
20236
20237            scheduleAppGcsLocked();
20238        }
20239    }
20240
20241    /**
20242     * If all looks good, perform GCs on all processes waiting for them.
20243     */
20244    final void performAppGcsIfAppropriateLocked() {
20245        if (canGcNowLocked()) {
20246            performAppGcsLocked();
20247            return;
20248        }
20249        // Still not idle, wait some more.
20250        scheduleAppGcsLocked();
20251    }
20252
20253    /**
20254     * Schedule the execution of all pending app GCs.
20255     */
20256    final void scheduleAppGcsLocked() {
20257        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
20258
20259        if (mProcessesToGc.size() > 0) {
20260            // Schedule a GC for the time to the next process.
20261            ProcessRecord proc = mProcessesToGc.get(0);
20262            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
20263
20264            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
20265            long now = SystemClock.uptimeMillis();
20266            if (when < (now+GC_TIMEOUT)) {
20267                when = now + GC_TIMEOUT;
20268            }
20269            mHandler.sendMessageAtTime(msg, when);
20270        }
20271    }
20272
20273    /**
20274     * Add a process to the array of processes waiting to be GCed.  Keeps the
20275     * list in sorted order by the last GC time.  The process can't already be
20276     * on the list.
20277     */
20278    final void addProcessToGcListLocked(ProcessRecord proc) {
20279        boolean added = false;
20280        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
20281            if (mProcessesToGc.get(i).lastRequestedGc <
20282                    proc.lastRequestedGc) {
20283                added = true;
20284                mProcessesToGc.add(i+1, proc);
20285                break;
20286            }
20287        }
20288        if (!added) {
20289            mProcessesToGc.add(0, proc);
20290        }
20291    }
20292
20293    /**
20294     * Set up to ask a process to GC itself.  This will either do it
20295     * immediately, or put it on the list of processes to gc the next
20296     * time things are idle.
20297     */
20298    final void scheduleAppGcLocked(ProcessRecord app) {
20299        long now = SystemClock.uptimeMillis();
20300        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
20301            return;
20302        }
20303        if (!mProcessesToGc.contains(app)) {
20304            addProcessToGcListLocked(app);
20305            scheduleAppGcsLocked();
20306        }
20307    }
20308
20309    final void checkExcessivePowerUsageLocked(boolean doKills) {
20310        updateCpuStatsNow();
20311
20312        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20313        boolean doWakeKills = doKills;
20314        boolean doCpuKills = doKills;
20315        if (mLastPowerCheckRealtime == 0) {
20316            doWakeKills = false;
20317        }
20318        if (mLastPowerCheckUptime == 0) {
20319            doCpuKills = false;
20320        }
20321        if (stats.isScreenOn()) {
20322            doWakeKills = false;
20323        }
20324        final long curRealtime = SystemClock.elapsedRealtime();
20325        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
20326        final long curUptime = SystemClock.uptimeMillis();
20327        final long uptimeSince = curUptime - mLastPowerCheckUptime;
20328        mLastPowerCheckRealtime = curRealtime;
20329        mLastPowerCheckUptime = curUptime;
20330        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
20331            doWakeKills = false;
20332        }
20333        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
20334            doCpuKills = false;
20335        }
20336        int i = mLruProcesses.size();
20337        while (i > 0) {
20338            i--;
20339            ProcessRecord app = mLruProcesses.get(i);
20340            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20341                long wtime;
20342                synchronized (stats) {
20343                    wtime = stats.getProcessWakeTime(app.info.uid,
20344                            app.pid, curRealtime);
20345                }
20346                long wtimeUsed = wtime - app.lastWakeTime;
20347                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
20348                if (DEBUG_POWER) {
20349                    StringBuilder sb = new StringBuilder(128);
20350                    sb.append("Wake for ");
20351                    app.toShortString(sb);
20352                    sb.append(": over ");
20353                    TimeUtils.formatDuration(realtimeSince, sb);
20354                    sb.append(" used ");
20355                    TimeUtils.formatDuration(wtimeUsed, sb);
20356                    sb.append(" (");
20357                    sb.append((wtimeUsed*100)/realtimeSince);
20358                    sb.append("%)");
20359                    Slog.i(TAG_POWER, sb.toString());
20360                    sb.setLength(0);
20361                    sb.append("CPU for ");
20362                    app.toShortString(sb);
20363                    sb.append(": over ");
20364                    TimeUtils.formatDuration(uptimeSince, sb);
20365                    sb.append(" used ");
20366                    TimeUtils.formatDuration(cputimeUsed, sb);
20367                    sb.append(" (");
20368                    sb.append((cputimeUsed*100)/uptimeSince);
20369                    sb.append("%)");
20370                    Slog.i(TAG_POWER, sb.toString());
20371                }
20372                // If a process has held a wake lock for more
20373                // than 50% of the time during this period,
20374                // that sounds bad.  Kill!
20375                if (doWakeKills && realtimeSince > 0
20376                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
20377                    synchronized (stats) {
20378                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
20379                                realtimeSince, wtimeUsed);
20380                    }
20381                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
20382                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
20383                } else if (doCpuKills && uptimeSince > 0
20384                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
20385                    synchronized (stats) {
20386                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
20387                                uptimeSince, cputimeUsed);
20388                    }
20389                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
20390                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
20391                } else {
20392                    app.lastWakeTime = wtime;
20393                    app.lastCpuTime = app.curCpuTime;
20394                }
20395            }
20396        }
20397    }
20398
20399    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
20400            long nowElapsed) {
20401        boolean success = true;
20402
20403        if (app.curRawAdj != app.setRawAdj) {
20404            app.setRawAdj = app.curRawAdj;
20405        }
20406
20407        int changes = 0;
20408
20409        if (app.curAdj != app.setAdj) {
20410            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
20411            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20412                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
20413                    + app.adjType);
20414            app.setAdj = app.curAdj;
20415            app.verifiedAdj = ProcessList.INVALID_ADJ;
20416        }
20417
20418        if (app.setSchedGroup != app.curSchedGroup) {
20419            int oldSchedGroup = app.setSchedGroup;
20420            app.setSchedGroup = app.curSchedGroup;
20421            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20422                    "Setting sched group of " + app.processName
20423                    + " to " + app.curSchedGroup);
20424            if (app.waitingToKill != null && app.curReceiver == null
20425                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
20426                app.kill(app.waitingToKill, true);
20427                success = false;
20428            } else {
20429                int processGroup;
20430                switch (app.curSchedGroup) {
20431                    case ProcessList.SCHED_GROUP_BACKGROUND:
20432                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
20433                        break;
20434                    case ProcessList.SCHED_GROUP_TOP_APP:
20435                    case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
20436                        processGroup = Process.THREAD_GROUP_TOP_APP;
20437                        break;
20438                    default:
20439                        processGroup = Process.THREAD_GROUP_DEFAULT;
20440                        break;
20441                }
20442                long oldId = Binder.clearCallingIdentity();
20443                try {
20444                    Process.setProcessGroup(app.pid, processGroup);
20445                    if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
20446                        // do nothing if we already switched to RT
20447                        if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20448                            // Switch VR thread for app to SCHED_FIFO
20449                            if (mInVrMode && app.vrThreadTid != 0) {
20450                                try {
20451                                    Process.setThreadScheduler(app.vrThreadTid,
20452                                        Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20453                                } catch (IllegalArgumentException e) {
20454                                    // thread died, ignore
20455                                }
20456                            }
20457                            if (mUseFifoUiScheduling) {
20458                                // Switch UI pipeline for app to SCHED_FIFO
20459                                app.savedPriority = Process.getThreadPriority(app.pid);
20460                                try {
20461                                    Process.setThreadScheduler(app.pid,
20462                                        Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20463                                } catch (IllegalArgumentException e) {
20464                                    // thread died, ignore
20465                                }
20466                                if (app.renderThreadTid != 0) {
20467                                    try {
20468                                        Process.setThreadScheduler(app.renderThreadTid,
20469                                            Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20470                                    } catch (IllegalArgumentException e) {
20471                                        // thread died, ignore
20472                                    }
20473                                    if (DEBUG_OOM_ADJ) {
20474                                        Slog.d("UI_FIFO", "Set RenderThread (TID " +
20475                                            app.renderThreadTid + ") to FIFO");
20476                                    }
20477                                } else {
20478                                    if (DEBUG_OOM_ADJ) {
20479                                        Slog.d("UI_FIFO", "Not setting RenderThread TID");
20480                                    }
20481                                }
20482                            } else {
20483                                // Boost priority for top app UI and render threads
20484                                Process.setThreadPriority(app.pid, -10);
20485                                if (app.renderThreadTid != 0) {
20486                                    try {
20487                                        Process.setThreadPriority(app.renderThreadTid, -10);
20488                                    } catch (IllegalArgumentException e) {
20489                                        // thread died, ignore
20490                                    }
20491                                }
20492                            }
20493                        }
20494                    } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
20495                               app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20496                        // Reset VR thread to SCHED_OTHER
20497                        // Safe to do even if we're not in VR mode
20498                        if (app.vrThreadTid != 0) {
20499                            Process.setThreadScheduler(app.vrThreadTid, Process.SCHED_OTHER, 0);
20500                        }
20501                        if (mUseFifoUiScheduling) {
20502                            // Reset UI pipeline to SCHED_OTHER
20503                            Process.setThreadScheduler(app.pid, Process.SCHED_OTHER, 0);
20504                            Process.setThreadPriority(app.pid, app.savedPriority);
20505                            if (app.renderThreadTid != 0) {
20506                                Process.setThreadScheduler(app.renderThreadTid,
20507                                    Process.SCHED_OTHER, 0);
20508                                Process.setThreadPriority(app.renderThreadTid, -4);
20509                            }
20510                        } else {
20511                            // Reset priority for top app UI and render threads
20512                            Process.setThreadPriority(app.pid, 0);
20513                            if (app.renderThreadTid != 0) {
20514                                Process.setThreadPriority(app.renderThreadTid, 0);
20515                            }
20516                        }
20517                    }
20518                } catch (Exception e) {
20519                    Slog.w(TAG, "Failed setting process group of " + app.pid
20520                            + " to " + app.curSchedGroup);
20521                    e.printStackTrace();
20522                } finally {
20523                    Binder.restoreCallingIdentity(oldId);
20524                }
20525            }
20526        }
20527        if (app.repForegroundActivities != app.foregroundActivities) {
20528            app.repForegroundActivities = app.foregroundActivities;
20529            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20530        }
20531        if (app.repProcState != app.curProcState) {
20532            app.repProcState = app.curProcState;
20533            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20534            if (app.thread != null) {
20535                try {
20536                    if (false) {
20537                        //RuntimeException h = new RuntimeException("here");
20538                        Slog.i(TAG, "Sending new process state " + app.repProcState
20539                                + " to " + app /*, h*/);
20540                    }
20541                    app.thread.setProcessState(app.repProcState);
20542                } catch (RemoteException e) {
20543                }
20544            }
20545        }
20546        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20547                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20548            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20549                // Experimental code to more aggressively collect pss while
20550                // running test...  the problem is that this tends to collect
20551                // the data right when a process is transitioning between process
20552                // states, which well tend to give noisy data.
20553                long start = SystemClock.uptimeMillis();
20554                long pss = Debug.getPss(app.pid, mTmpLong, null);
20555                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20556                mPendingPssProcesses.remove(app);
20557                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20558                        + " to " + app.curProcState + ": "
20559                        + (SystemClock.uptimeMillis()-start) + "ms");
20560            }
20561            app.lastStateTime = now;
20562            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20563                    mTestPssMode, isSleepingLocked(), now);
20564            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20565                    + ProcessList.makeProcStateString(app.setProcState) + " to "
20566                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20567                    + (app.nextPssTime-now) + ": " + app);
20568        } else {
20569            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20570                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20571                    mTestPssMode)))) {
20572                requestPssLocked(app, app.setProcState);
20573                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20574                        mTestPssMode, isSleepingLocked(), now);
20575            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20576                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20577        }
20578        if (app.setProcState != app.curProcState) {
20579            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20580                    "Proc state change of " + app.processName
20581                            + " to " + app.curProcState);
20582            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20583            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20584            if (setImportant && !curImportant) {
20585                // This app is no longer something we consider important enough to allow to
20586                // use arbitrary amounts of battery power.  Note
20587                // its current wake lock time to later know to kill it if
20588                // it is not behaving well.
20589                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20590                synchronized (stats) {
20591                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20592                            app.pid, nowElapsed);
20593                }
20594                app.lastCpuTime = app.curCpuTime;
20595
20596            }
20597            // Inform UsageStats of important process state change
20598            // Must be called before updating setProcState
20599            maybeUpdateUsageStatsLocked(app, nowElapsed);
20600
20601            app.setProcState = app.curProcState;
20602            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20603                app.notCachedSinceIdle = false;
20604            }
20605            if (!doingAll) {
20606                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20607            } else {
20608                app.procStateChanged = true;
20609            }
20610        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20611                > USAGE_STATS_INTERACTION_INTERVAL) {
20612            // For apps that sit around for a long time in the interactive state, we need
20613            // to report this at least once a day so they don't go idle.
20614            maybeUpdateUsageStatsLocked(app, nowElapsed);
20615        }
20616
20617        if (changes != 0) {
20618            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20619                    "Changes in " + app + ": " + changes);
20620            int i = mPendingProcessChanges.size()-1;
20621            ProcessChangeItem item = null;
20622            while (i >= 0) {
20623                item = mPendingProcessChanges.get(i);
20624                if (item.pid == app.pid) {
20625                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20626                            "Re-using existing item: " + item);
20627                    break;
20628                }
20629                i--;
20630            }
20631            if (i < 0) {
20632                // No existing item in pending changes; need a new one.
20633                final int NA = mAvailProcessChanges.size();
20634                if (NA > 0) {
20635                    item = mAvailProcessChanges.remove(NA-1);
20636                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20637                            "Retrieving available item: " + item);
20638                } else {
20639                    item = new ProcessChangeItem();
20640                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20641                            "Allocating new item: " + item);
20642                }
20643                item.changes = 0;
20644                item.pid = app.pid;
20645                item.uid = app.info.uid;
20646                if (mPendingProcessChanges.size() == 0) {
20647                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20648                            "*** Enqueueing dispatch processes changed!");
20649                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20650                }
20651                mPendingProcessChanges.add(item);
20652            }
20653            item.changes |= changes;
20654            item.processState = app.repProcState;
20655            item.foregroundActivities = app.repForegroundActivities;
20656            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20657                    "Item " + Integer.toHexString(System.identityHashCode(item))
20658                    + " " + app.toShortString() + ": changes=" + item.changes
20659                    + " procState=" + item.processState
20660                    + " foreground=" + item.foregroundActivities
20661                    + " type=" + app.adjType + " source=" + app.adjSource
20662                    + " target=" + app.adjTarget);
20663        }
20664
20665        return success;
20666    }
20667
20668    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20669        final UidRecord.ChangeItem pendingChange;
20670        if (uidRec == null || uidRec.pendingChange == null) {
20671            if (mPendingUidChanges.size() == 0) {
20672                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20673                        "*** Enqueueing dispatch uid changed!");
20674                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20675            }
20676            final int NA = mAvailUidChanges.size();
20677            if (NA > 0) {
20678                pendingChange = mAvailUidChanges.remove(NA-1);
20679                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20680                        "Retrieving available item: " + pendingChange);
20681            } else {
20682                pendingChange = new UidRecord.ChangeItem();
20683                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20684                        "Allocating new item: " + pendingChange);
20685            }
20686            if (uidRec != null) {
20687                uidRec.pendingChange = pendingChange;
20688                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20689                    // If this uid is going away, and we haven't yet reported it is gone,
20690                    // then do so now.
20691                    change = UidRecord.CHANGE_GONE_IDLE;
20692                }
20693            } else if (uid < 0) {
20694                throw new IllegalArgumentException("No UidRecord or uid");
20695            }
20696            pendingChange.uidRecord = uidRec;
20697            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20698            mPendingUidChanges.add(pendingChange);
20699        } else {
20700            pendingChange = uidRec.pendingChange;
20701            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20702                change = UidRecord.CHANGE_GONE_IDLE;
20703            }
20704        }
20705        pendingChange.change = change;
20706        pendingChange.processState = uidRec != null
20707                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20708    }
20709
20710    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20711            String authority) {
20712        if (app == null) return;
20713        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20714            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20715            if (userState == null) return;
20716            final long now = SystemClock.elapsedRealtime();
20717            Long lastReported = userState.mProviderLastReportedFg.get(authority);
20718            if (lastReported == null || lastReported < now - 60 * 1000L) {
20719                if (mSystemReady) {
20720                    // Cannot touch the user stats if not system ready
20721                    mUsageStatsService.reportContentProviderUsage(
20722                            authority, providerPkgName, app.userId);
20723                }
20724                userState.mProviderLastReportedFg.put(authority, now);
20725            }
20726        }
20727    }
20728
20729    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20730        if (DEBUG_USAGE_STATS) {
20731            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20732                    + "] state changes: old = " + app.setProcState + ", new = "
20733                    + app.curProcState);
20734        }
20735        if (mUsageStatsService == null) {
20736            return;
20737        }
20738        boolean isInteraction;
20739        // To avoid some abuse patterns, we are going to be careful about what we consider
20740        // to be an app interaction.  Being the top activity doesn't count while the display
20741        // is sleeping, nor do short foreground services.
20742        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20743            isInteraction = true;
20744            app.fgInteractionTime = 0;
20745        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20746            if (app.fgInteractionTime == 0) {
20747                app.fgInteractionTime = nowElapsed;
20748                isInteraction = false;
20749            } else {
20750                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20751            }
20752        } else {
20753            // If the app was being forced to the foreground, by say a Toast, then
20754            // no need to treat it as an interaction
20755            isInteraction = app.forcingToForeground == null
20756                    && app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20757            app.fgInteractionTime = 0;
20758        }
20759        if (isInteraction && (!app.reportedInteraction
20760                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20761            app.interactionEventTime = nowElapsed;
20762            String[] packages = app.getPackageList();
20763            if (packages != null) {
20764                for (int i = 0; i < packages.length; i++) {
20765                    mUsageStatsService.reportEvent(packages[i], app.userId,
20766                            UsageEvents.Event.SYSTEM_INTERACTION);
20767                }
20768            }
20769        }
20770        app.reportedInteraction = isInteraction;
20771        if (!isInteraction) {
20772            app.interactionEventTime = 0;
20773        }
20774    }
20775
20776    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20777        if (proc.thread != null) {
20778            if (proc.baseProcessTracker != null) {
20779                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20780            }
20781        }
20782    }
20783
20784    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20785            ProcessRecord TOP_APP, boolean doingAll, long now) {
20786        if (app.thread == null) {
20787            return false;
20788        }
20789
20790        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20791
20792        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20793    }
20794
20795    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20796            boolean oomAdj) {
20797        if (isForeground != proc.foregroundServices) {
20798            proc.foregroundServices = isForeground;
20799            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20800                    proc.info.uid);
20801            if (isForeground) {
20802                if (curProcs == null) {
20803                    curProcs = new ArrayList<ProcessRecord>();
20804                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20805                }
20806                if (!curProcs.contains(proc)) {
20807                    curProcs.add(proc);
20808                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20809                            proc.info.packageName, proc.info.uid);
20810                }
20811            } else {
20812                if (curProcs != null) {
20813                    if (curProcs.remove(proc)) {
20814                        mBatteryStatsService.noteEvent(
20815                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20816                                proc.info.packageName, proc.info.uid);
20817                        if (curProcs.size() <= 0) {
20818                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20819                        }
20820                    }
20821                }
20822            }
20823            if (oomAdj) {
20824                updateOomAdjLocked();
20825            }
20826        }
20827    }
20828
20829    private final ActivityRecord resumedAppLocked() {
20830        ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
20831        String pkg;
20832        int uid;
20833        if (act != null) {
20834            pkg = act.packageName;
20835            uid = act.info.applicationInfo.uid;
20836        } else {
20837            pkg = null;
20838            uid = -1;
20839        }
20840        // Has the UID or resumed package name changed?
20841        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20842                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20843            if (mCurResumedPackage != null) {
20844                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20845                        mCurResumedPackage, mCurResumedUid);
20846            }
20847            mCurResumedPackage = pkg;
20848            mCurResumedUid = uid;
20849            if (mCurResumedPackage != null) {
20850                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20851                        mCurResumedPackage, mCurResumedUid);
20852            }
20853        }
20854        return act;
20855    }
20856
20857    final boolean updateOomAdjLocked(ProcessRecord app) {
20858        final ActivityRecord TOP_ACT = resumedAppLocked();
20859        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20860        final boolean wasCached = app.cached;
20861
20862        mAdjSeq++;
20863
20864        // This is the desired cached adjusment we want to tell it to use.
20865        // If our app is currently cached, we know it, and that is it.  Otherwise,
20866        // we don't know it yet, and it needs to now be cached we will then
20867        // need to do a complete oom adj.
20868        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20869                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20870        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20871                SystemClock.uptimeMillis());
20872        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20873            // Changed to/from cached state, so apps after it in the LRU
20874            // list may also be changed.
20875            updateOomAdjLocked();
20876        }
20877        return success;
20878    }
20879
20880    final void updateOomAdjLocked() {
20881        final ActivityRecord TOP_ACT = resumedAppLocked();
20882        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20883        final long now = SystemClock.uptimeMillis();
20884        final long nowElapsed = SystemClock.elapsedRealtime();
20885        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20886        final int N = mLruProcesses.size();
20887
20888        if (false) {
20889            RuntimeException e = new RuntimeException();
20890            e.fillInStackTrace();
20891            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20892        }
20893
20894        // Reset state in all uid records.
20895        for (int i=mActiveUids.size()-1; i>=0; i--) {
20896            final UidRecord uidRec = mActiveUids.valueAt(i);
20897            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20898                    "Starting update of " + uidRec);
20899            uidRec.reset();
20900        }
20901
20902        mStackSupervisor.rankTaskLayersIfNeeded();
20903
20904        mAdjSeq++;
20905        mNewNumServiceProcs = 0;
20906        mNewNumAServiceProcs = 0;
20907
20908        final int emptyProcessLimit;
20909        final int cachedProcessLimit;
20910        if (mProcessLimit <= 0) {
20911            emptyProcessLimit = cachedProcessLimit = 0;
20912        } else if (mProcessLimit == 1) {
20913            emptyProcessLimit = 1;
20914            cachedProcessLimit = 0;
20915        } else {
20916            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20917            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20918        }
20919
20920        // Let's determine how many processes we have running vs.
20921        // how many slots we have for background processes; we may want
20922        // to put multiple processes in a slot of there are enough of
20923        // them.
20924        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20925                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20926        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20927        if (numEmptyProcs > cachedProcessLimit) {
20928            // If there are more empty processes than our limit on cached
20929            // processes, then use the cached process limit for the factor.
20930            // This ensures that the really old empty processes get pushed
20931            // down to the bottom, so if we are running low on memory we will
20932            // have a better chance at keeping around more cached processes
20933            // instead of a gazillion empty processes.
20934            numEmptyProcs = cachedProcessLimit;
20935        }
20936        int emptyFactor = numEmptyProcs/numSlots;
20937        if (emptyFactor < 1) emptyFactor = 1;
20938        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20939        if (cachedFactor < 1) cachedFactor = 1;
20940        int stepCached = 0;
20941        int stepEmpty = 0;
20942        int numCached = 0;
20943        int numEmpty = 0;
20944        int numTrimming = 0;
20945
20946        mNumNonCachedProcs = 0;
20947        mNumCachedHiddenProcs = 0;
20948
20949        // First update the OOM adjustment for each of the
20950        // application processes based on their current state.
20951        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20952        int nextCachedAdj = curCachedAdj+1;
20953        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20954        int nextEmptyAdj = curEmptyAdj+2;
20955        for (int i=N-1; i>=0; i--) {
20956            ProcessRecord app = mLruProcesses.get(i);
20957            if (!app.killedByAm && app.thread != null) {
20958                app.procStateChanged = false;
20959                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20960
20961                // If we haven't yet assigned the final cached adj
20962                // to the process, do that now.
20963                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20964                    switch (app.curProcState) {
20965                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20966                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20967                            // This process is a cached process holding activities...
20968                            // assign it the next cached value for that type, and then
20969                            // step that cached level.
20970                            app.curRawAdj = curCachedAdj;
20971                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20972                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20973                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20974                                    + ")");
20975                            if (curCachedAdj != nextCachedAdj) {
20976                                stepCached++;
20977                                if (stepCached >= cachedFactor) {
20978                                    stepCached = 0;
20979                                    curCachedAdj = nextCachedAdj;
20980                                    nextCachedAdj += 2;
20981                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20982                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20983                                    }
20984                                }
20985                            }
20986                            break;
20987                        default:
20988                            // For everything else, assign next empty cached process
20989                            // level and bump that up.  Note that this means that
20990                            // long-running services that have dropped down to the
20991                            // cached level will be treated as empty (since their process
20992                            // state is still as a service), which is what we want.
20993                            app.curRawAdj = curEmptyAdj;
20994                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20995                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20996                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20997                                    + ")");
20998                            if (curEmptyAdj != nextEmptyAdj) {
20999                                stepEmpty++;
21000                                if (stepEmpty >= emptyFactor) {
21001                                    stepEmpty = 0;
21002                                    curEmptyAdj = nextEmptyAdj;
21003                                    nextEmptyAdj += 2;
21004                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
21005                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
21006                                    }
21007                                }
21008                            }
21009                            break;
21010                    }
21011                }
21012
21013                applyOomAdjLocked(app, true, now, nowElapsed);
21014
21015                // Count the number of process types.
21016                switch (app.curProcState) {
21017                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
21018                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
21019                        mNumCachedHiddenProcs++;
21020                        numCached++;
21021                        if (numCached > cachedProcessLimit) {
21022                            app.kill("cached #" + numCached, true);
21023                        }
21024                        break;
21025                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
21026                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
21027                                && app.lastActivityTime < oldTime) {
21028                            app.kill("empty for "
21029                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
21030                                    / 1000) + "s", true);
21031                        } else {
21032                            numEmpty++;
21033                            if (numEmpty > emptyProcessLimit) {
21034                                app.kill("empty #" + numEmpty, true);
21035                            }
21036                        }
21037                        break;
21038                    default:
21039                        mNumNonCachedProcs++;
21040                        break;
21041                }
21042
21043                if (app.isolated && app.services.size() <= 0) {
21044                    // If this is an isolated process, and there are no
21045                    // services running in it, then the process is no longer
21046                    // needed.  We agressively kill these because we can by
21047                    // definition not re-use the same process again, and it is
21048                    // good to avoid having whatever code was running in them
21049                    // left sitting around after no longer needed.
21050                    app.kill("isolated not needed", true);
21051                } else {
21052                    // Keeping this process, update its uid.
21053                    final UidRecord uidRec = app.uidRecord;
21054                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
21055                        uidRec.curProcState = app.curProcState;
21056                    }
21057                }
21058
21059                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21060                        && !app.killedByAm) {
21061                    numTrimming++;
21062                }
21063            }
21064        }
21065
21066        mNumServiceProcs = mNewNumServiceProcs;
21067
21068        // Now determine the memory trimming level of background processes.
21069        // Unfortunately we need to start at the back of the list to do this
21070        // properly.  We only do this if the number of background apps we
21071        // are managing to keep around is less than half the maximum we desire;
21072        // if we are keeping a good number around, we'll let them use whatever
21073        // memory they want.
21074        final int numCachedAndEmpty = numCached + numEmpty;
21075        int memFactor;
21076        if (numCached <= ProcessList.TRIM_CACHED_APPS
21077                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
21078            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
21079                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
21080            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
21081                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
21082            } else {
21083                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
21084            }
21085        } else {
21086            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
21087        }
21088        // We always allow the memory level to go up (better).  We only allow it to go
21089        // down if we are in a state where that is allowed, *and* the total number of processes
21090        // has gone down since last time.
21091        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
21092                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
21093                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
21094        if (memFactor > mLastMemoryLevel) {
21095            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
21096                memFactor = mLastMemoryLevel;
21097                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
21098            }
21099        }
21100        if (memFactor != mLastMemoryLevel) {
21101            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
21102        }
21103        mLastMemoryLevel = memFactor;
21104        mLastNumProcesses = mLruProcesses.size();
21105        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
21106        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
21107        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
21108            if (mLowRamStartTime == 0) {
21109                mLowRamStartTime = now;
21110            }
21111            int step = 0;
21112            int fgTrimLevel;
21113            switch (memFactor) {
21114                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
21115                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
21116                    break;
21117                case ProcessStats.ADJ_MEM_FACTOR_LOW:
21118                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
21119                    break;
21120                default:
21121                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
21122                    break;
21123            }
21124            int factor = numTrimming/3;
21125            int minFactor = 2;
21126            if (mHomeProcess != null) minFactor++;
21127            if (mPreviousProcess != null) minFactor++;
21128            if (factor < minFactor) factor = minFactor;
21129            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
21130            for (int i=N-1; i>=0; i--) {
21131                ProcessRecord app = mLruProcesses.get(i);
21132                if (allChanged || app.procStateChanged) {
21133                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
21134                    app.procStateChanged = false;
21135                }
21136                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21137                        && !app.killedByAm) {
21138                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
21139                        try {
21140                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21141                                    "Trimming memory of " + app.processName + " to " + curLevel);
21142                            app.thread.scheduleTrimMemory(curLevel);
21143                        } catch (RemoteException e) {
21144                        }
21145                        if (false) {
21146                            // For now we won't do this; our memory trimming seems
21147                            // to be good enough at this point that destroying
21148                            // activities causes more harm than good.
21149                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
21150                                    && app != mHomeProcess && app != mPreviousProcess) {
21151                                // Need to do this on its own message because the stack may not
21152                                // be in a consistent state at this point.
21153                                // For these apps we will also finish their activities
21154                                // to help them free memory.
21155                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
21156                            }
21157                        }
21158                    }
21159                    app.trimMemoryLevel = curLevel;
21160                    step++;
21161                    if (step >= factor) {
21162                        step = 0;
21163                        switch (curLevel) {
21164                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
21165                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
21166                                break;
21167                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
21168                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21169                                break;
21170                        }
21171                    }
21172                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21173                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
21174                            && app.thread != null) {
21175                        try {
21176                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21177                                    "Trimming memory of heavy-weight " + app.processName
21178                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21179                            app.thread.scheduleTrimMemory(
21180                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21181                        } catch (RemoteException e) {
21182                        }
21183                    }
21184                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21185                } else {
21186                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21187                            || app.systemNoUi) && app.pendingUiClean) {
21188                        // If this application is now in the background and it
21189                        // had done UI, then give it the special trim level to
21190                        // have it free UI resources.
21191                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
21192                        if (app.trimMemoryLevel < level && app.thread != null) {
21193                            try {
21194                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21195                                        "Trimming memory of bg-ui " + app.processName
21196                                        + " to " + level);
21197                                app.thread.scheduleTrimMemory(level);
21198                            } catch (RemoteException e) {
21199                            }
21200                        }
21201                        app.pendingUiClean = false;
21202                    }
21203                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
21204                        try {
21205                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21206                                    "Trimming memory of fg " + app.processName
21207                                    + " to " + fgTrimLevel);
21208                            app.thread.scheduleTrimMemory(fgTrimLevel);
21209                        } catch (RemoteException e) {
21210                        }
21211                    }
21212                    app.trimMemoryLevel = fgTrimLevel;
21213                }
21214            }
21215        } else {
21216            if (mLowRamStartTime != 0) {
21217                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
21218                mLowRamStartTime = 0;
21219            }
21220            for (int i=N-1; i>=0; i--) {
21221                ProcessRecord app = mLruProcesses.get(i);
21222                if (allChanged || app.procStateChanged) {
21223                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
21224                    app.procStateChanged = false;
21225                }
21226                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21227                        || app.systemNoUi) && app.pendingUiClean) {
21228                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
21229                            && app.thread != null) {
21230                        try {
21231                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21232                                    "Trimming memory of ui hidden " + app.processName
21233                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21234                            app.thread.scheduleTrimMemory(
21235                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21236                        } catch (RemoteException e) {
21237                        }
21238                    }
21239                    app.pendingUiClean = false;
21240                }
21241                app.trimMemoryLevel = 0;
21242            }
21243        }
21244
21245        if (mAlwaysFinishActivities) {
21246            // Need to do this on its own message because the stack may not
21247            // be in a consistent state at this point.
21248            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
21249        }
21250
21251        if (allChanged) {
21252            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
21253        }
21254
21255        // Update from any uid changes.
21256        for (int i=mActiveUids.size()-1; i>=0; i--) {
21257            final UidRecord uidRec = mActiveUids.valueAt(i);
21258            int uidChange = UidRecord.CHANGE_PROCSTATE;
21259            if (uidRec.setProcState != uidRec.curProcState) {
21260                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21261                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
21262                        + " to " + uidRec.curProcState);
21263                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
21264                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
21265                        uidRec.lastBackgroundTime = nowElapsed;
21266                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
21267                            // Note: the background settle time is in elapsed realtime, while
21268                            // the handler time base is uptime.  All this means is that we may
21269                            // stop background uids later than we had intended, but that only
21270                            // happens because the device was sleeping so we are okay anyway.
21271                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
21272                        }
21273                    }
21274                } else {
21275                    if (uidRec.idle) {
21276                        uidChange = UidRecord.CHANGE_ACTIVE;
21277                        uidRec.idle = false;
21278                    }
21279                    uidRec.lastBackgroundTime = 0;
21280                }
21281                uidRec.setProcState = uidRec.curProcState;
21282                enqueueUidChangeLocked(uidRec, -1, uidChange);
21283                noteUidProcessState(uidRec.uid, uidRec.curProcState);
21284            }
21285        }
21286
21287        if (mProcessStats.shouldWriteNowLocked(now)) {
21288            mHandler.post(new Runnable() {
21289                @Override public void run() {
21290                    synchronized (ActivityManagerService.this) {
21291                        mProcessStats.writeStateAsyncLocked();
21292                    }
21293                }
21294            });
21295        }
21296
21297        if (DEBUG_OOM_ADJ) {
21298            final long duration = SystemClock.uptimeMillis() - now;
21299            if (false) {
21300                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
21301                        new RuntimeException("here").fillInStackTrace());
21302            } else {
21303                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
21304            }
21305        }
21306    }
21307
21308    final void idleUids() {
21309        synchronized (this) {
21310            final long nowElapsed = SystemClock.elapsedRealtime();
21311            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
21312            long nextTime = 0;
21313            for (int i=mActiveUids.size()-1; i>=0; i--) {
21314                final UidRecord uidRec = mActiveUids.valueAt(i);
21315                final long bgTime = uidRec.lastBackgroundTime;
21316                if (bgTime > 0 && !uidRec.idle) {
21317                    if (bgTime <= maxBgTime) {
21318                        uidRec.idle = true;
21319                        doStopUidLocked(uidRec.uid, uidRec);
21320                    } else {
21321                        if (nextTime == 0 || nextTime > bgTime) {
21322                            nextTime = bgTime;
21323                        }
21324                    }
21325                }
21326            }
21327            if (nextTime > 0) {
21328                mHandler.removeMessages(IDLE_UIDS_MSG);
21329                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
21330                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
21331            }
21332        }
21333    }
21334
21335    final void runInBackgroundDisabled(int uid) {
21336        synchronized (this) {
21337            UidRecord uidRec = mActiveUids.get(uid);
21338            if (uidRec != null) {
21339                // This uid is actually running...  should it be considered background now?
21340                if (uidRec.idle) {
21341                    doStopUidLocked(uidRec.uid, uidRec);
21342                }
21343            } else {
21344                // This uid isn't actually running...  still send a report about it being "stopped".
21345                doStopUidLocked(uid, null);
21346            }
21347        }
21348    }
21349
21350    final void doStopUidLocked(int uid, final UidRecord uidRec) {
21351        mServices.stopInBackgroundLocked(uid);
21352        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
21353    }
21354
21355    final void trimApplications() {
21356        synchronized (this) {
21357            int i;
21358
21359            // First remove any unused application processes whose package
21360            // has been removed.
21361            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
21362                final ProcessRecord app = mRemovedProcesses.get(i);
21363                if (app.activities.size() == 0
21364                        && app.curReceiver == null && app.services.size() == 0) {
21365                    Slog.i(
21366                        TAG, "Exiting empty application process "
21367                        + app.toShortString() + " ("
21368                        + (app.thread != null ? app.thread.asBinder() : null)
21369                        + ")\n");
21370                    if (app.pid > 0 && app.pid != MY_PID) {
21371                        app.kill("empty", false);
21372                    } else {
21373                        try {
21374                            app.thread.scheduleExit();
21375                        } catch (Exception e) {
21376                            // Ignore exceptions.
21377                        }
21378                    }
21379                    cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
21380                    mRemovedProcesses.remove(i);
21381
21382                    if (app.persistent) {
21383                        addAppLocked(app.info, false, null /* ABI override */);
21384                    }
21385                }
21386            }
21387
21388            // Now update the oom adj for all processes.
21389            updateOomAdjLocked();
21390        }
21391    }
21392
21393    /** This method sends the specified signal to each of the persistent apps */
21394    public void signalPersistentProcesses(int sig) throws RemoteException {
21395        if (sig != Process.SIGNAL_USR1) {
21396            throw new SecurityException("Only SIGNAL_USR1 is allowed");
21397        }
21398
21399        synchronized (this) {
21400            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
21401                    != PackageManager.PERMISSION_GRANTED) {
21402                throw new SecurityException("Requires permission "
21403                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
21404            }
21405
21406            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
21407                ProcessRecord r = mLruProcesses.get(i);
21408                if (r.thread != null && r.persistent) {
21409                    Process.sendSignal(r.pid, sig);
21410                }
21411            }
21412        }
21413    }
21414
21415    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
21416        if (proc == null || proc == mProfileProc) {
21417            proc = mProfileProc;
21418            profileType = mProfileType;
21419            clearProfilerLocked();
21420        }
21421        if (proc == null) {
21422            return;
21423        }
21424        try {
21425            proc.thread.profilerControl(false, null, profileType);
21426        } catch (RemoteException e) {
21427            throw new IllegalStateException("Process disappeared");
21428        }
21429    }
21430
21431    private void clearProfilerLocked() {
21432        if (mProfileFd != null) {
21433            try {
21434                mProfileFd.close();
21435            } catch (IOException e) {
21436            }
21437        }
21438        mProfileApp = null;
21439        mProfileProc = null;
21440        mProfileFile = null;
21441        mProfileType = 0;
21442        mAutoStopProfiler = false;
21443        mSamplingInterval = 0;
21444    }
21445
21446    public boolean profileControl(String process, int userId, boolean start,
21447            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
21448
21449        try {
21450            synchronized (this) {
21451                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21452                // its own permission.
21453                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21454                        != PackageManager.PERMISSION_GRANTED) {
21455                    throw new SecurityException("Requires permission "
21456                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21457                }
21458
21459                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
21460                    throw new IllegalArgumentException("null profile info or fd");
21461                }
21462
21463                ProcessRecord proc = null;
21464                if (process != null) {
21465                    proc = findProcessLocked(process, userId, "profileControl");
21466                }
21467
21468                if (start && (proc == null || proc.thread == null)) {
21469                    throw new IllegalArgumentException("Unknown process: " + process);
21470                }
21471
21472                if (start) {
21473                    stopProfilerLocked(null, 0);
21474                    setProfileApp(proc.info, proc.processName, profilerInfo);
21475                    mProfileProc = proc;
21476                    mProfileType = profileType;
21477                    ParcelFileDescriptor fd = profilerInfo.profileFd;
21478                    try {
21479                        fd = fd.dup();
21480                    } catch (IOException e) {
21481                        fd = null;
21482                    }
21483                    profilerInfo.profileFd = fd;
21484                    proc.thread.profilerControl(start, profilerInfo, profileType);
21485                    fd = null;
21486                    mProfileFd = null;
21487                } else {
21488                    stopProfilerLocked(proc, profileType);
21489                    if (profilerInfo != null && profilerInfo.profileFd != null) {
21490                        try {
21491                            profilerInfo.profileFd.close();
21492                        } catch (IOException e) {
21493                        }
21494                    }
21495                }
21496
21497                return true;
21498            }
21499        } catch (RemoteException e) {
21500            throw new IllegalStateException("Process disappeared");
21501        } finally {
21502            if (profilerInfo != null && profilerInfo.profileFd != null) {
21503                try {
21504                    profilerInfo.profileFd.close();
21505                } catch (IOException e) {
21506                }
21507            }
21508        }
21509    }
21510
21511    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
21512        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21513                userId, true, ALLOW_FULL_ONLY, callName, null);
21514        ProcessRecord proc = null;
21515        try {
21516            int pid = Integer.parseInt(process);
21517            synchronized (mPidsSelfLocked) {
21518                proc = mPidsSelfLocked.get(pid);
21519            }
21520        } catch (NumberFormatException e) {
21521        }
21522
21523        if (proc == null) {
21524            ArrayMap<String, SparseArray<ProcessRecord>> all
21525                    = mProcessNames.getMap();
21526            SparseArray<ProcessRecord> procs = all.get(process);
21527            if (procs != null && procs.size() > 0) {
21528                proc = procs.valueAt(0);
21529                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
21530                    for (int i=1; i<procs.size(); i++) {
21531                        ProcessRecord thisProc = procs.valueAt(i);
21532                        if (thisProc.userId == userId) {
21533                            proc = thisProc;
21534                            break;
21535                        }
21536                    }
21537                }
21538            }
21539        }
21540
21541        return proc;
21542    }
21543
21544    public boolean dumpHeap(String process, int userId, boolean managed,
21545            String path, ParcelFileDescriptor fd) throws RemoteException {
21546
21547        try {
21548            synchronized (this) {
21549                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21550                // its own permission (same as profileControl).
21551                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21552                        != PackageManager.PERMISSION_GRANTED) {
21553                    throw new SecurityException("Requires permission "
21554                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21555                }
21556
21557                if (fd == null) {
21558                    throw new IllegalArgumentException("null fd");
21559                }
21560
21561                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
21562                if (proc == null || proc.thread == null) {
21563                    throw new IllegalArgumentException("Unknown process: " + process);
21564                }
21565
21566                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21567                if (!isDebuggable) {
21568                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21569                        throw new SecurityException("Process not debuggable: " + proc);
21570                    }
21571                }
21572
21573                proc.thread.dumpHeap(managed, path, fd);
21574                fd = null;
21575                return true;
21576            }
21577        } catch (RemoteException e) {
21578            throw new IllegalStateException("Process disappeared");
21579        } finally {
21580            if (fd != null) {
21581                try {
21582                    fd.close();
21583                } catch (IOException e) {
21584                }
21585            }
21586        }
21587    }
21588
21589    @Override
21590    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
21591            String reportPackage) {
21592        if (processName != null) {
21593            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
21594                    "setDumpHeapDebugLimit()");
21595        } else {
21596            synchronized (mPidsSelfLocked) {
21597                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
21598                if (proc == null) {
21599                    throw new SecurityException("No process found for calling pid "
21600                            + Binder.getCallingPid());
21601                }
21602                if (!Build.IS_DEBUGGABLE
21603                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21604                    throw new SecurityException("Not running a debuggable build");
21605                }
21606                processName = proc.processName;
21607                uid = proc.uid;
21608                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
21609                    throw new SecurityException("Package " + reportPackage + " is not running in "
21610                            + proc);
21611                }
21612            }
21613        }
21614        synchronized (this) {
21615            if (maxMemSize > 0) {
21616                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
21617            } else {
21618                if (uid != 0) {
21619                    mMemWatchProcesses.remove(processName, uid);
21620                } else {
21621                    mMemWatchProcesses.getMap().remove(processName);
21622                }
21623            }
21624        }
21625    }
21626
21627    @Override
21628    public void dumpHeapFinished(String path) {
21629        synchronized (this) {
21630            if (Binder.getCallingPid() != mMemWatchDumpPid) {
21631                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
21632                        + " does not match last pid " + mMemWatchDumpPid);
21633                return;
21634            }
21635            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
21636                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
21637                        + " does not match last path " + mMemWatchDumpFile);
21638                return;
21639            }
21640            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21641            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21642        }
21643    }
21644
21645    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21646    public void monitor() {
21647        synchronized (this) { }
21648    }
21649
21650    void onCoreSettingsChange(Bundle settings) {
21651        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21652            ProcessRecord processRecord = mLruProcesses.get(i);
21653            try {
21654                if (processRecord.thread != null) {
21655                    processRecord.thread.setCoreSettings(settings);
21656                }
21657            } catch (RemoteException re) {
21658                /* ignore */
21659            }
21660        }
21661    }
21662
21663    // Multi-user methods
21664
21665    /**
21666     * Start user, if its not already running, but don't bring it to foreground.
21667     */
21668    @Override
21669    public boolean startUserInBackground(final int userId) {
21670        return mUserController.startUser(userId, /* foreground */ false);
21671    }
21672
21673    @Override
21674    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21675        return mUserController.unlockUser(userId, token, secret, listener);
21676    }
21677
21678    @Override
21679    public boolean switchUser(final int targetUserId) {
21680        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21681        int currentUserId;
21682        UserInfo targetUserInfo;
21683        synchronized (this) {
21684            currentUserId = mUserController.getCurrentUserIdLocked();
21685            targetUserInfo = mUserController.getUserInfo(targetUserId);
21686            if (targetUserId == currentUserId) {
21687                Slog.i(TAG, "user #" + targetUserId + " is already the current user");
21688                return true;
21689            }
21690            if (targetUserInfo == null) {
21691                Slog.w(TAG, "No user info for user #" + targetUserId);
21692                return false;
21693            }
21694            if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
21695                Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
21696                        + " when device is in demo mode");
21697                return false;
21698            }
21699            if (!targetUserInfo.supportsSwitchTo()) {
21700                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21701                return false;
21702            }
21703            if (targetUserInfo.isManagedProfile()) {
21704                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21705                return false;
21706            }
21707            mUserController.setTargetUserIdLocked(targetUserId);
21708        }
21709        if (mUserController.mUserSwitchUiEnabled) {
21710            UserInfo currentUserInfo = mUserController.getUserInfo(currentUserId);
21711            Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21712            mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21713            mUiHandler.sendMessage(mHandler.obtainMessage(
21714                    START_USER_SWITCH_UI_MSG, userNames));
21715        } else {
21716            mHandler.removeMessages(START_USER_SWITCH_FG_MSG);
21717            mHandler.sendMessage(mHandler.obtainMessage(
21718                    START_USER_SWITCH_FG_MSG, targetUserId, 0));
21719        }
21720        return true;
21721    }
21722
21723    void scheduleStartProfilesLocked() {
21724        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21725            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21726                    DateUtils.SECOND_IN_MILLIS);
21727        }
21728    }
21729
21730    @Override
21731    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21732        return mUserController.stopUser(userId, force, callback);
21733    }
21734
21735    @Override
21736    public UserInfo getCurrentUser() {
21737        return mUserController.getCurrentUser();
21738    }
21739
21740    String getStartedUserState(int userId) {
21741        synchronized (this) {
21742            final UserState userState = mUserController.getStartedUserStateLocked(userId);
21743            return UserState.stateToString(userState.state);
21744        }
21745    }
21746
21747    @Override
21748    public boolean isUserRunning(int userId, int flags) {
21749        if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
21750                && checkCallingPermission(INTERACT_ACROSS_USERS)
21751                    != PackageManager.PERMISSION_GRANTED) {
21752            String msg = "Permission Denial: isUserRunning() from pid="
21753                    + Binder.getCallingPid()
21754                    + ", uid=" + Binder.getCallingUid()
21755                    + " requires " + INTERACT_ACROSS_USERS;
21756            Slog.w(TAG, msg);
21757            throw new SecurityException(msg);
21758        }
21759        synchronized (this) {
21760            return mUserController.isUserRunningLocked(userId, flags);
21761        }
21762    }
21763
21764    @Override
21765    public int[] getRunningUserIds() {
21766        if (checkCallingPermission(INTERACT_ACROSS_USERS)
21767                != PackageManager.PERMISSION_GRANTED) {
21768            String msg = "Permission Denial: isUserRunning() from pid="
21769                    + Binder.getCallingPid()
21770                    + ", uid=" + Binder.getCallingUid()
21771                    + " requires " + INTERACT_ACROSS_USERS;
21772            Slog.w(TAG, msg);
21773            throw new SecurityException(msg);
21774        }
21775        synchronized (this) {
21776            return mUserController.getStartedUserArrayLocked();
21777        }
21778    }
21779
21780    @Override
21781    public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
21782        mUserController.registerUserSwitchObserver(observer, name);
21783    }
21784
21785    @Override
21786    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21787        mUserController.unregisterUserSwitchObserver(observer);
21788    }
21789
21790    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21791        if (info == null) return null;
21792        ApplicationInfo newInfo = new ApplicationInfo(info);
21793        newInfo.initForUser(userId);
21794        return newInfo;
21795    }
21796
21797    public boolean isUserStopped(int userId) {
21798        synchronized (this) {
21799            return mUserController.getStartedUserStateLocked(userId) == null;
21800        }
21801    }
21802
21803    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21804        if (aInfo == null
21805                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21806            return aInfo;
21807        }
21808
21809        ActivityInfo info = new ActivityInfo(aInfo);
21810        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21811        return info;
21812    }
21813
21814    private boolean processSanityChecksLocked(ProcessRecord process) {
21815        if (process == null || process.thread == null) {
21816            return false;
21817        }
21818
21819        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21820        if (!isDebuggable) {
21821            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21822                return false;
21823            }
21824        }
21825
21826        return true;
21827    }
21828
21829    public boolean startBinderTracking() throws RemoteException {
21830        synchronized (this) {
21831            mBinderTransactionTrackingEnabled = true;
21832            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21833            // permission (same as profileControl).
21834            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21835                    != PackageManager.PERMISSION_GRANTED) {
21836                throw new SecurityException("Requires permission "
21837                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21838            }
21839
21840            for (int i = 0; i < mLruProcesses.size(); i++) {
21841                ProcessRecord process = mLruProcesses.get(i);
21842                if (!processSanityChecksLocked(process)) {
21843                    continue;
21844                }
21845                try {
21846                    process.thread.startBinderTracking();
21847                } catch (RemoteException e) {
21848                    Log.v(TAG, "Process disappared");
21849                }
21850            }
21851            return true;
21852        }
21853    }
21854
21855    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21856        try {
21857            synchronized (this) {
21858                mBinderTransactionTrackingEnabled = false;
21859                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21860                // permission (same as profileControl).
21861                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21862                        != PackageManager.PERMISSION_GRANTED) {
21863                    throw new SecurityException("Requires permission "
21864                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21865                }
21866
21867                if (fd == null) {
21868                    throw new IllegalArgumentException("null fd");
21869                }
21870
21871                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21872                pw.println("Binder transaction traces for all processes.\n");
21873                for (ProcessRecord process : mLruProcesses) {
21874                    if (!processSanityChecksLocked(process)) {
21875                        continue;
21876                    }
21877
21878                    pw.println("Traces for process: " + process.processName);
21879                    pw.flush();
21880                    try {
21881                        TransferPipe tp = new TransferPipe();
21882                        try {
21883                            process.thread.stopBinderTrackingAndDump(
21884                                    tp.getWriteFd().getFileDescriptor());
21885                            tp.go(fd.getFileDescriptor());
21886                        } finally {
21887                            tp.kill();
21888                        }
21889                    } catch (IOException e) {
21890                        pw.println("Failure while dumping IPC traces from " + process +
21891                                ".  Exception: " + e);
21892                        pw.flush();
21893                    } catch (RemoteException e) {
21894                        pw.println("Got a RemoteException while dumping IPC traces from " +
21895                                process + ".  Exception: " + e);
21896                        pw.flush();
21897                    }
21898                }
21899                fd = null;
21900                return true;
21901            }
21902        } finally {
21903            if (fd != null) {
21904                try {
21905                    fd.close();
21906                } catch (IOException e) {
21907                }
21908            }
21909        }
21910    }
21911
21912    private final class LocalService extends ActivityManagerInternal {
21913        @Override
21914        public void onWakefulnessChanged(int wakefulness) {
21915            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21916        }
21917
21918        @Override
21919        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21920                String processName, String abiOverride, int uid, Runnable crashHandler) {
21921            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21922                    processName, abiOverride, uid, crashHandler);
21923        }
21924
21925        @Override
21926        public SleepToken acquireSleepToken(String tag) {
21927            Preconditions.checkNotNull(tag);
21928
21929            ComponentName requestedVrService = null;
21930            ComponentName callingVrActivity = null;
21931            int userId = -1;
21932            synchronized (ActivityManagerService.this) {
21933                final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
21934                if (resumedActivity != null) {
21935                    requestedVrService = resumedActivity.requestedVrComponent;
21936                    callingVrActivity = resumedActivity.info.getComponentName();
21937                    userId = resumedActivity.userId;
21938                }
21939            }
21940
21941            if (requestedVrService != null) {
21942                applyVrMode(false, requestedVrService, userId, callingVrActivity, true);
21943            }
21944
21945            synchronized (ActivityManagerService.this) {
21946                SleepTokenImpl token = new SleepTokenImpl(tag);
21947                mSleepTokens.add(token);
21948                updateSleepIfNeededLocked();
21949                return token;
21950            }
21951        }
21952
21953        @Override
21954        public ComponentName getHomeActivityForUser(int userId) {
21955            synchronized (ActivityManagerService.this) {
21956                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21957                return homeActivity == null ? null : homeActivity.realActivity;
21958            }
21959        }
21960
21961        @Override
21962        public void onUserRemoved(int userId) {
21963            synchronized (ActivityManagerService.this) {
21964                ActivityManagerService.this.onUserStoppedLocked(userId);
21965            }
21966        }
21967
21968        @Override
21969        public void onLocalVoiceInteractionStarted(IBinder activity,
21970                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21971            synchronized (ActivityManagerService.this) {
21972                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21973                        voiceSession, voiceInteractor);
21974            }
21975        }
21976
21977        @Override
21978        public void notifyStartingWindowDrawn() {
21979            synchronized (ActivityManagerService.this) {
21980                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21981            }
21982        }
21983
21984        @Override
21985        public void notifyAppTransitionStarting(int reason) {
21986            synchronized (ActivityManagerService.this) {
21987                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21988            }
21989        }
21990
21991        @Override
21992        public void notifyAppTransitionFinished() {
21993            synchronized (ActivityManagerService.this) {
21994                mStackSupervisor.notifyAppTransitionDone();
21995            }
21996        }
21997
21998        @Override
21999        public void notifyAppTransitionCancelled() {
22000            synchronized (ActivityManagerService.this) {
22001                mStackSupervisor.notifyAppTransitionDone();
22002            }
22003        }
22004
22005        @Override
22006        public List<IBinder> getTopVisibleActivities() {
22007            synchronized (ActivityManagerService.this) {
22008                return mStackSupervisor.getTopVisibleActivities();
22009            }
22010        }
22011
22012        @Override
22013        public void notifyDockedStackMinimizedChanged(boolean minimized) {
22014            synchronized (ActivityManagerService.this) {
22015                mStackSupervisor.setDockedStackMinimized(minimized);
22016            }
22017        }
22018
22019        @Override
22020        public void killForegroundAppsForUser(int userHandle) {
22021            synchronized (ActivityManagerService.this) {
22022                final ArrayList<ProcessRecord> procs = new ArrayList<>();
22023                final int NP = mProcessNames.getMap().size();
22024                for (int ip = 0; ip < NP; ip++) {
22025                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
22026                    final int NA = apps.size();
22027                    for (int ia = 0; ia < NA; ia++) {
22028                        final ProcessRecord app = apps.valueAt(ia);
22029                        if (app.persistent) {
22030                            // We don't kill persistent processes.
22031                            continue;
22032                        }
22033                        if (app.removed) {
22034                            procs.add(app);
22035                        } else if (app.userId == userHandle && app.foregroundActivities) {
22036                            app.removed = true;
22037                            procs.add(app);
22038                        }
22039                    }
22040                }
22041
22042                final int N = procs.size();
22043                for (int i = 0; i < N; i++) {
22044                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
22045                }
22046            }
22047        }
22048
22049        @Override
22050        public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
22051            if (!(target instanceof PendingIntentRecord)) {
22052                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
22053                return;
22054            }
22055            ((PendingIntentRecord) target).setWhitelistDuration(duration);
22056        }
22057
22058        @Override
22059        public void updatePersistentConfigurationForUser(@NonNull Configuration values,
22060                int userId) {
22061            Preconditions.checkNotNull(values, "Configuration must not be null");
22062            Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
22063            synchronized (ActivityManagerService.this) {
22064                updateConfigurationLocked(values, null, false, true, userId,
22065                        false /* deferResume */);
22066            }
22067        }
22068
22069        @Override
22070        public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
22071                Bundle bOptions) {
22072            Preconditions.checkNotNull(intents, "intents");
22073            final String[] resolvedTypes = new String[intents.length];
22074            for (int i = 0; i < intents.length; i++) {
22075                resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
22076            }
22077
22078            // UID of the package on user userId.
22079            // "= 0" is needed because otherwise catch(RemoteException) would make it look like
22080            // packageUid may not be initialized.
22081            int packageUid = 0;
22082            try {
22083                packageUid = AppGlobals.getPackageManager().getPackageUid(
22084                        packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
22085            } catch (RemoteException e) {
22086                // Shouldn't happen.
22087            }
22088
22089            synchronized (ActivityManagerService.this) {
22090                return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
22091                        /*resultTo*/ null, bOptions, userId);
22092            }
22093        }
22094
22095        @Override
22096        public int getUidProcessState(int uid) {
22097            return getUidState(uid);
22098        }
22099    }
22100
22101    private final class SleepTokenImpl extends SleepToken {
22102        private final String mTag;
22103        private final long mAcquireTime;
22104
22105        public SleepTokenImpl(String tag) {
22106            mTag = tag;
22107            mAcquireTime = SystemClock.uptimeMillis();
22108        }
22109
22110        @Override
22111        public void release() {
22112            synchronized (ActivityManagerService.this) {
22113                if (mSleepTokens.remove(this)) {
22114                    updateSleepIfNeededLocked();
22115                }
22116            }
22117        }
22118
22119        @Override
22120        public String toString() {
22121            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
22122        }
22123    }
22124
22125    /**
22126     * An implementation of IAppTask, that allows an app to manage its own tasks via
22127     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
22128     * only the process that calls getAppTasks() can call the AppTask methods.
22129     */
22130    class AppTaskImpl extends IAppTask.Stub {
22131        private int mTaskId;
22132        private int mCallingUid;
22133
22134        public AppTaskImpl(int taskId, int callingUid) {
22135            mTaskId = taskId;
22136            mCallingUid = callingUid;
22137        }
22138
22139        private void checkCaller() {
22140            if (mCallingUid != Binder.getCallingUid()) {
22141                throw new SecurityException("Caller " + mCallingUid
22142                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
22143            }
22144        }
22145
22146        @Override
22147        public void finishAndRemoveTask() {
22148            checkCaller();
22149
22150            synchronized (ActivityManagerService.this) {
22151                long origId = Binder.clearCallingIdentity();
22152                try {
22153                    // We remove the task from recents to preserve backwards
22154                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
22155                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22156                    }
22157                } finally {
22158                    Binder.restoreCallingIdentity(origId);
22159                }
22160            }
22161        }
22162
22163        @Override
22164        public ActivityManager.RecentTaskInfo getTaskInfo() {
22165            checkCaller();
22166
22167            synchronized (ActivityManagerService.this) {
22168                long origId = Binder.clearCallingIdentity();
22169                try {
22170                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22171                    if (tr == null) {
22172                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22173                    }
22174                    return createRecentTaskInfoFromTaskRecord(tr);
22175                } finally {
22176                    Binder.restoreCallingIdentity(origId);
22177                }
22178            }
22179        }
22180
22181        @Override
22182        public void moveToFront() {
22183            checkCaller();
22184            // Will bring task to front if it already has a root activity.
22185            final long origId = Binder.clearCallingIdentity();
22186            try {
22187                synchronized (this) {
22188                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
22189                }
22190            } finally {
22191                Binder.restoreCallingIdentity(origId);
22192            }
22193        }
22194
22195        @Override
22196        public int startActivity(IBinder whoThread, String callingPackage,
22197                Intent intent, String resolvedType, Bundle bOptions) {
22198            checkCaller();
22199
22200            int callingUser = UserHandle.getCallingUserId();
22201            TaskRecord tr;
22202            IApplicationThread appThread;
22203            synchronized (ActivityManagerService.this) {
22204                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22205                if (tr == null) {
22206                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22207                }
22208                appThread = ApplicationThreadNative.asInterface(whoThread);
22209                if (appThread == null) {
22210                    throw new IllegalArgumentException("Bad app thread " + appThread);
22211                }
22212            }
22213            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
22214                    resolvedType, null, null, null, null, 0, 0, null, null,
22215                    null, bOptions, false, callingUser, null, tr);
22216        }
22217
22218        @Override
22219        public void setExcludeFromRecents(boolean exclude) {
22220            checkCaller();
22221
22222            synchronized (ActivityManagerService.this) {
22223                long origId = Binder.clearCallingIdentity();
22224                try {
22225                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22226                    if (tr == null) {
22227                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22228                    }
22229                    Intent intent = tr.getBaseIntent();
22230                    if (exclude) {
22231                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22232                    } else {
22233                        intent.setFlags(intent.getFlags()
22234                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22235                    }
22236                } finally {
22237                    Binder.restoreCallingIdentity(origId);
22238                }
22239            }
22240        }
22241    }
22242
22243    /**
22244     * Kill processes for the user with id userId and that depend on the package named packageName
22245     */
22246    @Override
22247    public void killPackageDependents(String packageName, int userId) {
22248        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
22249        if (packageName == null) {
22250            throw new NullPointerException(
22251                    "Cannot kill the dependents of a package without its name.");
22252        }
22253
22254        long callingId = Binder.clearCallingIdentity();
22255        IPackageManager pm = AppGlobals.getPackageManager();
22256        int pkgUid = -1;
22257        try {
22258            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
22259        } catch (RemoteException e) {
22260        }
22261        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
22262            throw new IllegalArgumentException(
22263                    "Cannot kill dependents of non-existing package " + packageName);
22264        }
22265        try {
22266            synchronized(this) {
22267                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
22268                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
22269                        "dep: " + packageName);
22270            }
22271        } finally {
22272            Binder.restoreCallingIdentity(callingId);
22273        }
22274    }
22275
22276    @Override
22277    public boolean canBypassWorkChallenge(PendingIntent intent) throws RemoteException {
22278        final int userId = intent.getCreatorUserHandle().getIdentifier();
22279        if (!mUserController.isUserRunningLocked(userId, ActivityManager.FLAG_AND_LOCKED)) {
22280            return false;
22281        }
22282        IIntentSender target = intent.getTarget();
22283        if (!(target instanceof PendingIntentRecord)) {
22284            return false;
22285        }
22286        final PendingIntentRecord record = (PendingIntentRecord) target;
22287        final ResolveInfo rInfo = mStackSupervisor.resolveIntent(record.key.requestIntent,
22288                record.key.requestResolvedType, userId, PackageManager.MATCH_DIRECT_BOOT_AWARE);
22289        // For direct boot aware activities, they can be shown without triggering a work challenge
22290        // before the profile user is unlocked.
22291        return rInfo != null && rInfo.activityInfo != null;
22292    }
22293}
22294