ActivityManagerService.java revision 7dac366a7f72e3d3f0c7e26616ec0ee55efe1fcd
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 com.android.internal.telephony.TelephonyIntents;
20import com.google.android.collect.Lists;
21import com.google.android.collect.Maps;
22import com.android.internal.R;
23import com.android.internal.annotations.GuardedBy;
24import com.android.internal.app.AssistUtils;
25import com.android.internal.app.DumpHeapActivity;
26import com.android.internal.app.IAppOpsCallback;
27import com.android.internal.app.IAppOpsService;
28import com.android.internal.app.IVoiceInteractor;
29import com.android.internal.app.ProcessMap;
30import com.android.internal.app.SystemUserHomeActivity;
31import com.android.internal.app.procstats.ProcessStats;
32import com.android.internal.os.BackgroundThread;
33import com.android.internal.os.BatteryStatsImpl;
34import com.android.internal.os.IResultReceiver;
35import com.android.internal.os.ProcessCpuTracker;
36import com.android.internal.os.TransferPipe;
37import com.android.internal.os.Zygote;
38import com.android.internal.os.InstallerConnection.InstallerException;
39import com.android.internal.util.ArrayUtils;
40import com.android.internal.util.FastPrintWriter;
41import com.android.internal.util.FastXmlSerializer;
42import com.android.internal.util.MemInfoReader;
43import com.android.internal.util.Preconditions;
44import com.android.internal.util.ProgressReporter;
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.annotation.UserIdInt;
68import android.app.Activity;
69import android.app.ActivityManager;
70import android.app.ActivityManager.RunningTaskInfo;
71import android.app.ActivityManager.StackId;
72import android.app.ActivityManager.StackInfo;
73import android.app.ActivityManager.TaskThumbnailInfo;
74import android.app.ActivityManagerInternal;
75import android.app.ActivityManagerInternal.SleepToken;
76import android.app.ActivityManagerNative;
77import android.app.ActivityOptions;
78import android.app.ActivityThread;
79import android.app.AlertDialog;
80import android.app.AppGlobals;
81import android.app.AppOpsManager;
82import android.app.ApplicationErrorReport;
83import android.app.ApplicationThreadNative;
84import android.app.BroadcastOptions;
85import android.app.Dialog;
86import android.app.IActivityContainer;
87import android.app.IActivityContainerCallback;
88import android.app.IActivityController;
89import android.app.IAppTask;
90import android.app.IApplicationThread;
91import android.app.IInstrumentationWatcher;
92import android.app.INotificationManager;
93import android.app.IProcessObserver;
94import android.app.IServiceConnection;
95import android.app.IStopUserCallback;
96import android.app.ITaskStackListener;
97import android.app.IUiAutomationConnection;
98import android.app.IUidObserver;
99import android.app.IUserSwitchObserver;
100import android.app.Instrumentation;
101import android.app.KeyguardManager;
102import android.app.Notification;
103import android.app.NotificationManager;
104import android.app.PendingIntent;
105import android.app.ProfilerInfo;
106import android.app.admin.DevicePolicyManager;
107import android.app.admin.DevicePolicyManagerInternal;
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.ShortcutServiceInternal;
146import android.content.pm.UserInfo;
147import android.content.res.CompatibilityInfo;
148import android.content.res.Configuration;
149import android.content.res.Resources;
150import android.database.ContentObserver;
151import android.graphics.Bitmap;
152import android.graphics.Point;
153import android.graphics.Rect;
154import android.location.LocationManager;
155import android.net.Proxy;
156import android.net.ProxyInfo;
157import android.net.Uri;
158import android.os.BatteryStats;
159import android.os.Binder;
160import android.os.Build;
161import android.os.Bundle;
162import android.os.Debug;
163import android.os.DropBoxManager;
164import android.os.Environment;
165import android.os.FactoryTest;
166import android.os.FileObserver;
167import android.os.FileUtils;
168import android.os.Handler;
169import android.os.IBinder;
170import android.os.IPermissionController;
171import android.os.IProcessInfoService;
172import android.os.IProgressListener;
173import android.os.LocaleList;
174import android.os.Looper;
175import android.os.Message;
176import android.os.Parcel;
177import android.os.ParcelFileDescriptor;
178import android.os.PersistableBundle;
179import android.os.PowerManager;
180import android.os.PowerManagerInternal;
181import android.os.Process;
182import android.os.RemoteCallbackList;
183import android.os.RemoteException;
184import android.os.ResultReceiver;
185import android.os.ServiceManager;
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.EventLog;
211import android.util.Log;
212import android.util.Pair;
213import android.util.PrintWriterPrinter;
214import android.util.Slog;
215import android.util.SparseArray;
216import android.util.TimeUtils;
217import android.util.Xml;
218import android.view.Display;
219import android.view.Gravity;
220import android.view.LayoutInflater;
221import android.view.View;
222import android.view.WindowManager;
223
224import java.io.File;
225import java.io.FileDescriptor;
226import java.io.FileInputStream;
227import java.io.FileNotFoundException;
228import java.io.FileOutputStream;
229import java.io.IOException;
230import java.io.InputStreamReader;
231import java.io.PrintWriter;
232import java.io.StringWriter;
233import java.lang.ref.WeakReference;
234import java.nio.charset.StandardCharsets;
235import java.util.ArrayList;
236import java.util.Arrays;
237import java.util.Collections;
238import java.util.Comparator;
239import java.util.HashMap;
240import java.util.HashSet;
241import java.util.Iterator;
242import java.util.List;
243import java.util.Locale;
244import java.util.Map;
245import java.util.Objects;
246import java.util.Set;
247import java.util.concurrent.atomic.AtomicBoolean;
248import java.util.concurrent.atomic.AtomicLong;
249
250import dalvik.system.VMRuntime;
251
252import libcore.io.IoUtils;
253import libcore.util.EmptyArray;
254
255import static android.Manifest.permission.INTERACT_ACROSS_USERS;
256import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
257import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
258import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
259import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
260import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
261import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
262import static android.app.ActivityManager.StackId.FIRST_STATIC_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.LAST_STATIC_STACK_ID;
268import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
269import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
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_UNAWARE;
274import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
275import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
276import static android.content.pm.PackageManager.PERMISSION_GRANTED;
277import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
278import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
279import static android.provider.Settings.Global.DEBUG_APP;
280import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
281import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
282import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
283import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
284import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
285import static android.provider.Settings.System.FONT_SCALE;
286import static com.android.internal.util.XmlUtils.readBooleanAttribute;
287import static com.android.internal.util.XmlUtils.readIntAttribute;
288import static com.android.internal.util.XmlUtils.readLongAttribute;
289import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
290import static com.android.internal.util.XmlUtils.writeIntAttribute;
291import static com.android.internal.util.XmlUtils.writeLongAttribute;
292import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
293import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
294import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
295import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
301import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
302import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
303import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
304import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
315import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
316import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
317import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
318import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
319import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
320import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
321import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
322import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
323import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
324import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
325import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
326import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
327import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
328import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
329import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
330import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
331import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
332import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
333import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
334import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
335import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
336import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
337import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
338import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
339import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
340import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
341import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
342import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
343import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
344import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
345import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
346import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
347import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
348import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
349import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
350import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
351import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
352import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
353import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
354import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
355import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
356import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
357import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
358import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
359import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
360import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
361import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
362import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
363import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
364import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
365import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
366import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
367import static org.xmlpull.v1.XmlPullParser.START_TAG;
368
369public final class ActivityManagerService extends ActivityManagerNative
370        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
371
372    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
373    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
374    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
375    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
376    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
377    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
378    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
379    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
380    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
381    private static final String TAG_LRU = TAG + POSTFIX_LRU;
382    private static final String TAG_MU = TAG + POSTFIX_MU;
383    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
384    private static final String TAG_POWER = TAG + POSTFIX_POWER;
385    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
386    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
387    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
388    private static final String TAG_PSS = TAG + POSTFIX_PSS;
389    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
390    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
391    private static final String TAG_STACK = TAG + POSTFIX_STACK;
392    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
393    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
394    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
395    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
396    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
397
398    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
399    // here so that while the job scheduler can depend on AMS, the other way around
400    // need not be the case.
401    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
402
403    /** Control over CPU and battery monitoring */
404    // write battery stats every 30 minutes.
405    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
406    static final boolean MONITOR_CPU_USAGE = true;
407    // don't sample cpu less than every 5 seconds.
408    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
409    // wait possibly forever for next cpu sample.
410    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
411    static final boolean MONITOR_THREAD_CPU_USAGE = false;
412
413    // The flags that are set for all calls we make to the package manager.
414    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
415
416    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
417
418    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
419
420    // Amount of time after a call to stopAppSwitches() during which we will
421    // prevent further untrusted switches from happening.
422    static final long APP_SWITCH_DELAY_TIME = 5*1000;
423
424    // How long we wait for a launched process to attach to the activity manager
425    // before we decide it's never going to come up for real.
426    static final int PROC_START_TIMEOUT = 10*1000;
427    // How long we wait for an attached process to publish its content providers
428    // before we decide it must be hung.
429    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
430
431    // How long we will retain processes hosting content providers in the "last activity"
432    // state before allowing them to drop down to the regular cached LRU list.  This is
433    // to avoid thrashing of provider processes under low memory situations.
434    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
435
436    // How long we wait for a launched process to attach to the activity manager
437    // before we decide it's never going to come up for real, when the process was
438    // started with a wrapper for instrumentation (such as Valgrind) because it
439    // could take much longer than usual.
440    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
441
442    // How long to wait after going idle before forcing apps to GC.
443    static final int GC_TIMEOUT = 5*1000;
444
445    // The minimum amount of time between successive GC requests for a process.
446    static final int GC_MIN_INTERVAL = 60*1000;
447
448    // The minimum amount of time between successive PSS requests for a process.
449    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
450
451    // The minimum amount of time between successive PSS requests for a process
452    // when the request is due to the memory state being lowered.
453    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
454
455    // The rate at which we check for apps using excessive power -- 15 mins.
456    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
457
458    // The minimum sample duration we will allow before deciding we have
459    // enough data on wake locks to start killing things.
460    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
461
462    // The minimum sample duration we will allow before deciding we have
463    // enough data on CPU usage to start killing things.
464    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
465
466    // How long we allow a receiver to run before giving up on it.
467    static final int BROADCAST_FG_TIMEOUT = 10*1000;
468    static final int BROADCAST_BG_TIMEOUT = 60*1000;
469
470    // How long we wait until we timeout on key dispatching.
471    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
472
473    // How long we wait until we timeout on key dispatching during instrumentation.
474    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
475
476    // This is the amount of time an app needs to be running a foreground service before
477    // we will consider it to be doing interaction for usage stats.
478    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
479
480    // Maximum amount of time we will allow to elapse before re-reporting usage stats
481    // interaction with foreground processes.
482    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
483
484    // This is the amount of time we allow an app to settle after it goes into the background,
485    // before we start restricting what it can do.
486    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
487
488    // How long to wait in getAssistContextExtras for the activity and foreground services
489    // to respond with the result.
490    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
491
492    // How long top wait when going through the modern assist (which doesn't need to block
493    // on getting this result before starting to launch its UI).
494    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
495
496    // Maximum number of persisted Uri grants a package is allowed
497    static final int MAX_PERSISTED_URI_GRANTS = 128;
498
499    static final int MY_PID = Process.myPid();
500
501    static final String[] EMPTY_STRING_ARRAY = new String[0];
502
503    // How many bytes to write into the dropbox log before truncating
504    static final int DROPBOX_MAX_SIZE = 256 * 1024;
505
506    // Access modes for handleIncomingUser.
507    static final int ALLOW_NON_FULL = 0;
508    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
509    static final int ALLOW_FULL_ONLY = 2;
510
511    // Delay in notifying task stack change listeners (in millis)
512    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
513
514    // Necessary ApplicationInfo flags to mark an app as persistent
515    private static final int PERSISTENT_MASK =
516            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
517
518    // Intent sent when remote bugreport collection has been completed
519    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
520            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
521
522    // Delay to disable app launch boost
523    static final int APP_BOOST_MESSAGE_DELAY = 3000;
524    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
525    static final int APP_BOOST_TIMEOUT = 2500;
526
527    // Used to indicate that a task is removed it should also be removed from recents.
528    private static final boolean REMOVE_FROM_RECENTS = true;
529    // Used to indicate that an app transition should be animated.
530    static final boolean ANIMATE = true;
531
532    // Determines whether to take full screen screenshots
533    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
534    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
535
536    private static native int nativeMigrateToBoost();
537    private static native int nativeMigrateFromBoost();
538    private boolean mIsBoosted = false;
539    private long mBoostStartTime = 0;
540
541    /** All system services */
542    SystemServiceManager mSystemServiceManager;
543
544    private Installer mInstaller;
545
546    /** Run all ActivityStacks through this */
547    final ActivityStackSupervisor mStackSupervisor;
548
549    final ActivityStarter mActivityStarter;
550
551    /** Task stack change listeners. */
552    private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
553            new RemoteCallbackList<ITaskStackListener>();
554
555    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
556
557    public IntentFirewall mIntentFirewall;
558
559    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
560    // default actuion automatically.  Important for devices without direct input
561    // devices.
562    private boolean mShowDialogs = true;
563    private boolean mInVrMode = false;
564
565    BroadcastQueue mFgBroadcastQueue;
566    BroadcastQueue mBgBroadcastQueue;
567    // Convenient for easy iteration over the queues. Foreground is first
568    // so that dispatch of foreground broadcasts gets precedence.
569    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
570
571    BroadcastQueue broadcastQueueForIntent(Intent intent) {
572        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
573        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
574                "Broadcast intent " + intent + " on "
575                + (isFg ? "foreground" : "background") + " queue");
576        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
577    }
578
579    /**
580     * Activity we have told the window manager to have key focus.
581     */
582    ActivityRecord mFocusedActivity = null;
583
584    /**
585     * User id of the last activity mFocusedActivity was set to.
586     */
587    private int mLastFocusedUserId;
588
589    /**
590     * If non-null, we are tracking the time the user spends in the currently focused app.
591     */
592    private AppTimeTracker mCurAppTimeTracker;
593
594    /**
595     * List of intents that were used to start the most recent tasks.
596     */
597    final RecentTasks mRecentTasks;
598
599    /**
600     * For addAppTask: cached of the last activity component that was added.
601     */
602    ComponentName mLastAddedTaskComponent;
603
604    /**
605     * For addAppTask: cached of the last activity uid that was added.
606     */
607    int mLastAddedTaskUid;
608
609    /**
610     * For addAppTask: cached of the last ActivityInfo that was added.
611     */
612    ActivityInfo mLastAddedTaskActivity;
613
614    /**
615     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
616     */
617    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
618
619    /**
620     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
621     */
622    String mDeviceOwnerName;
623
624    final UserController mUserController;
625
626    final AppErrors mAppErrors;
627
628    boolean mDoingSetFocusedActivity;
629
630    public boolean canShowErrorDialogs() {
631        return mShowDialogs && !mSleeping && !mShuttingDown;
632    }
633
634    // it's a semaphore; boost when 0->1, reset when 1->0
635    static ThreadLocal<Integer> sIsBoosted = new ThreadLocal<Integer>() {
636        @Override protected Integer initialValue() {
637            return 0;
638        }
639    };
640
641    static void boostPriorityForLockedSection() {
642        if (sIsBoosted.get() == 0) {
643            // boost to prio 118 while holding a global lock
644            Process.setThreadPriority(Process.myTid(), -2);
645            //Log.e(TAG, "PRIORITY BOOST:  set priority on TID " + Process.myTid());
646        }
647        int cur = sIsBoosted.get();
648        sIsBoosted.set(cur + 1);
649    }
650
651    static void resetPriorityAfterLockedSection() {
652        sIsBoosted.set(sIsBoosted.get() - 1);
653        if (sIsBoosted.get() == 0) {
654            //Log.e(TAG, "PRIORITY BOOST:  reset priority on TID " + Process.myTid());
655            Process.setThreadPriority(Process.myTid(), 0);
656        }
657    }
658    public class PendingAssistExtras extends Binder implements Runnable {
659        public final ActivityRecord activity;
660        public final Bundle extras;
661        public final Intent intent;
662        public final String hint;
663        public final IResultReceiver receiver;
664        public final int userHandle;
665        public boolean haveResult = false;
666        public Bundle result = null;
667        public AssistStructure structure = null;
668        public AssistContent content = null;
669        public Bundle receiverExtras;
670
671        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
672                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
673            activity = _activity;
674            extras = _extras;
675            intent = _intent;
676            hint = _hint;
677            receiver = _receiver;
678            receiverExtras = _receiverExtras;
679            userHandle = _userHandle;
680        }
681        @Override
682        public void run() {
683            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
684            synchronized (this) {
685                haveResult = true;
686                notifyAll();
687            }
688            pendingAssistExtrasTimedOut(this);
689        }
690    }
691
692    final ArrayList<PendingAssistExtras> mPendingAssistExtras
693            = new ArrayList<PendingAssistExtras>();
694
695    /**
696     * Process management.
697     */
698    final ProcessList mProcessList = new ProcessList();
699
700    /**
701     * All of the applications we currently have running organized by name.
702     * The keys are strings of the application package name (as
703     * returned by the package manager), and the keys are ApplicationRecord
704     * objects.
705     */
706    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
707
708    /**
709     * Tracking long-term execution of processes to look for abuse and other
710     * bad app behavior.
711     */
712    final ProcessStatsService mProcessStats;
713
714    /**
715     * The currently running isolated processes.
716     */
717    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
718
719    /**
720     * Counter for assigning isolated process uids, to avoid frequently reusing the
721     * same ones.
722     */
723    int mNextIsolatedProcessUid = 0;
724
725    /**
726     * The currently running heavy-weight process, if any.
727     */
728    ProcessRecord mHeavyWeightProcess = null;
729
730    /**
731     * All of the processes we currently have running organized by pid.
732     * The keys are the pid running the application.
733     *
734     * <p>NOTE: This object is protected by its own lock, NOT the global
735     * activity manager lock!
736     */
737    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
738
739    /**
740     * All of the processes that have been forced to be foreground.  The key
741     * is the pid of the caller who requested it (we hold a death
742     * link on it).
743     */
744    abstract class ForegroundToken implements IBinder.DeathRecipient {
745        int pid;
746        IBinder token;
747    }
748    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
749
750    /**
751     * List of records for processes that someone had tried to start before the
752     * system was ready.  We don't start them at that point, but ensure they
753     * are started by the time booting is complete.
754     */
755    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
756
757    /**
758     * List of persistent applications that are in the process
759     * of being started.
760     */
761    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
762
763    /**
764     * Processes that are being forcibly torn down.
765     */
766    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
767
768    /**
769     * List of running applications, sorted by recent usage.
770     * The first entry in the list is the least recently used.
771     */
772    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
773
774    /**
775     * Where in mLruProcesses that the processes hosting activities start.
776     */
777    int mLruProcessActivityStart = 0;
778
779    /**
780     * Where in mLruProcesses that the processes hosting services start.
781     * This is after (lower index) than mLruProcessesActivityStart.
782     */
783    int mLruProcessServiceStart = 0;
784
785    /**
786     * List of processes that should gc as soon as things are idle.
787     */
788    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
789
790    /**
791     * Processes we want to collect PSS data from.
792     */
793    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
794
795    private boolean mBinderTransactionTrackingEnabled = false;
796
797    /**
798     * Last time we requested PSS data of all processes.
799     */
800    long mLastFullPssTime = SystemClock.uptimeMillis();
801
802    /**
803     * If set, the next time we collect PSS data we should do a full collection
804     * with data from native processes and the kernel.
805     */
806    boolean mFullPssPending = false;
807
808    /**
809     * This is the process holding what we currently consider to be
810     * the "home" activity.
811     */
812    ProcessRecord mHomeProcess;
813
814    /**
815     * This is the process holding the activity the user last visited that
816     * is in a different process from the one they are currently in.
817     */
818    ProcessRecord mPreviousProcess;
819
820    /**
821     * The time at which the previous process was last visible.
822     */
823    long mPreviousProcessVisibleTime;
824
825    /**
826     * Track all uids that have actively running processes.
827     */
828    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
829
830    /**
831     * This is for verifying the UID report flow.
832     */
833    static final boolean VALIDATE_UID_STATES = true;
834    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
835
836    /**
837     * Packages that the user has asked to have run in screen size
838     * compatibility mode instead of filling the screen.
839     */
840    final CompatModePackages mCompatModePackages;
841
842    /**
843     * Set of IntentSenderRecord objects that are currently active.
844     */
845    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
846            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
847
848    /**
849     * Fingerprints (hashCode()) of stack traces that we've
850     * already logged DropBox entries for.  Guarded by itself.  If
851     * something (rogue user app) forces this over
852     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
853     */
854    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
855    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
856
857    /**
858     * Strict Mode background batched logging state.
859     *
860     * The string buffer is guarded by itself, and its lock is also
861     * used to determine if another batched write is already
862     * in-flight.
863     */
864    private final StringBuilder mStrictModeBuffer = new StringBuilder();
865
866    /**
867     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
868     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
869     */
870    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
871
872    /**
873     * Resolver for broadcast intents to registered receivers.
874     * Holds BroadcastFilter (subclass of IntentFilter).
875     */
876    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
877            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
878        @Override
879        protected boolean allowFilterResult(
880                BroadcastFilter filter, List<BroadcastFilter> dest) {
881            IBinder target = filter.receiverList.receiver.asBinder();
882            for (int i = dest.size() - 1; i >= 0; i--) {
883                if (dest.get(i).receiverList.receiver.asBinder() == target) {
884                    return false;
885                }
886            }
887            return true;
888        }
889
890        @Override
891        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
892            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
893                    || userId == filter.owningUserId) {
894                return super.newResult(filter, match, userId);
895            }
896            return null;
897        }
898
899        @Override
900        protected BroadcastFilter[] newArray(int size) {
901            return new BroadcastFilter[size];
902        }
903
904        @Override
905        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
906            return packageName.equals(filter.packageName);
907        }
908    };
909
910    /**
911     * State of all active sticky broadcasts per user.  Keys are the action of the
912     * sticky Intent, values are an ArrayList of all broadcasted intents with
913     * that action (which should usually be one).  The SparseArray is keyed
914     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
915     * for stickies that are sent to all users.
916     */
917    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
918            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
919
920    final ActiveServices mServices;
921
922    final static class Association {
923        final int mSourceUid;
924        final String mSourceProcess;
925        final int mTargetUid;
926        final ComponentName mTargetComponent;
927        final String mTargetProcess;
928
929        int mCount;
930        long mTime;
931
932        int mNesting;
933        long mStartTime;
934
935        // states of the source process when the bind occurred.
936        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
937        long mLastStateUptime;
938        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
939                - ActivityManager.MIN_PROCESS_STATE+1];
940
941        Association(int sourceUid, String sourceProcess, int targetUid,
942                ComponentName targetComponent, String targetProcess) {
943            mSourceUid = sourceUid;
944            mSourceProcess = sourceProcess;
945            mTargetUid = targetUid;
946            mTargetComponent = targetComponent;
947            mTargetProcess = targetProcess;
948        }
949    }
950
951    /**
952     * When service association tracking is enabled, this is all of the associations we
953     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
954     * -> association data.
955     */
956    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
957            mAssociations = new SparseArray<>();
958    boolean mTrackingAssociations;
959
960    /**
961     * Backup/restore process management
962     */
963    String mBackupAppName = null;
964    BackupRecord mBackupTarget = null;
965
966    final ProviderMap mProviderMap;
967
968    /**
969     * List of content providers who have clients waiting for them.  The
970     * application is currently being launched and the provider will be
971     * removed from this list once it is published.
972     */
973    final ArrayList<ContentProviderRecord> mLaunchingProviders
974            = new ArrayList<ContentProviderRecord>();
975
976    /**
977     * File storing persisted {@link #mGrantedUriPermissions}.
978     */
979    private final AtomicFile mGrantFile;
980
981    /** XML constants used in {@link #mGrantFile} */
982    private static final String TAG_URI_GRANTS = "uri-grants";
983    private static final String TAG_URI_GRANT = "uri-grant";
984    private static final String ATTR_USER_HANDLE = "userHandle";
985    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
986    private static final String ATTR_TARGET_USER_ID = "targetUserId";
987    private static final String ATTR_SOURCE_PKG = "sourcePkg";
988    private static final String ATTR_TARGET_PKG = "targetPkg";
989    private static final String ATTR_URI = "uri";
990    private static final String ATTR_MODE_FLAGS = "modeFlags";
991    private static final String ATTR_CREATED_TIME = "createdTime";
992    private static final String ATTR_PREFIX = "prefix";
993
994    /**
995     * Global set of specific {@link Uri} permissions that have been granted.
996     * This optimized lookup structure maps from {@link UriPermission#targetUid}
997     * to {@link UriPermission#uri} to {@link UriPermission}.
998     */
999    @GuardedBy("this")
1000    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1001            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1002
1003    public static class GrantUri {
1004        public final int sourceUserId;
1005        public final Uri uri;
1006        public boolean prefix;
1007
1008        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1009            this.sourceUserId = sourceUserId;
1010            this.uri = uri;
1011            this.prefix = prefix;
1012        }
1013
1014        @Override
1015        public int hashCode() {
1016            int hashCode = 1;
1017            hashCode = 31 * hashCode + sourceUserId;
1018            hashCode = 31 * hashCode + uri.hashCode();
1019            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1020            return hashCode;
1021        }
1022
1023        @Override
1024        public boolean equals(Object o) {
1025            if (o instanceof GrantUri) {
1026                GrantUri other = (GrantUri) o;
1027                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1028                        && prefix == other.prefix;
1029            }
1030            return false;
1031        }
1032
1033        @Override
1034        public String toString() {
1035            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1036            if (prefix) result += " [prefix]";
1037            return result;
1038        }
1039
1040        public String toSafeString() {
1041            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1042            if (prefix) result += " [prefix]";
1043            return result;
1044        }
1045
1046        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1047            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1048                    ContentProvider.getUriWithoutUserId(uri), false);
1049        }
1050    }
1051
1052    CoreSettingsObserver mCoreSettingsObserver;
1053
1054    FontScaleSettingObserver mFontScaleSettingObserver;
1055
1056    private final class FontScaleSettingObserver extends ContentObserver {
1057        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1058
1059        public FontScaleSettingObserver() {
1060            super(mHandler);
1061            ContentResolver resolver = mContext.getContentResolver();
1062            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1063        }
1064
1065        @Override
1066        public void onChange(boolean selfChange, Uri uri) {
1067            if (mFontScaleUri.equals(uri)) {
1068                updateFontScaleIfNeeded();
1069            }
1070        }
1071    }
1072
1073    /**
1074     * Thread-local storage used to carry caller permissions over through
1075     * indirect content-provider access.
1076     */
1077    private class Identity {
1078        public final IBinder token;
1079        public final int pid;
1080        public final int uid;
1081
1082        Identity(IBinder _token, int _pid, int _uid) {
1083            token = _token;
1084            pid = _pid;
1085            uid = _uid;
1086        }
1087    }
1088
1089    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1090
1091    /**
1092     * All information we have collected about the runtime performance of
1093     * any user id that can impact battery performance.
1094     */
1095    final BatteryStatsService mBatteryStatsService;
1096
1097    /**
1098     * Information about component usage
1099     */
1100    UsageStatsManagerInternal mUsageStatsService;
1101
1102    /**
1103     * Access to DeviceIdleController service.
1104     */
1105    DeviceIdleController.LocalService mLocalDeviceIdleController;
1106
1107    /**
1108     * Information about and control over application operations
1109     */
1110    final AppOpsService mAppOpsService;
1111
1112    /**
1113     * Current configuration information.  HistoryRecord objects are given
1114     * a reference to this object to indicate which configuration they are
1115     * currently running in, so this object must be kept immutable.
1116     */
1117    Configuration mConfiguration = new Configuration();
1118
1119    /**
1120     * Current sequencing integer of the configuration, for skipping old
1121     * configurations.
1122     */
1123    int mConfigurationSeq = 0;
1124
1125    boolean mSuppressResizeConfigChanges = false;
1126
1127    /**
1128     * Hardware-reported OpenGLES version.
1129     */
1130    final int GL_ES_VERSION;
1131
1132    /**
1133     * List of initialization arguments to pass to all processes when binding applications to them.
1134     * For example, references to the commonly used services.
1135     */
1136    HashMap<String, IBinder> mAppBindArgs;
1137
1138    /**
1139     * Temporary to avoid allocations.  Protected by main lock.
1140     */
1141    final StringBuilder mStringBuilder = new StringBuilder(256);
1142
1143    /**
1144     * Used to control how we initialize the service.
1145     */
1146    ComponentName mTopComponent;
1147    String mTopAction = Intent.ACTION_MAIN;
1148    String mTopData;
1149
1150    volatile boolean mProcessesReady = false;
1151    volatile boolean mSystemReady = false;
1152    volatile boolean mOnBattery = false;
1153    volatile int mFactoryTest;
1154
1155    @GuardedBy("this") boolean mBooting = false;
1156    @GuardedBy("this") boolean mCallFinishBooting = false;
1157    @GuardedBy("this") boolean mBootAnimationComplete = false;
1158    @GuardedBy("this") boolean mLaunchWarningShown = false;
1159    @GuardedBy("this") boolean mCheckedForSetup = false;
1160
1161    Context mContext;
1162
1163    /**
1164     * The time at which we will allow normal application switches again,
1165     * after a call to {@link #stopAppSwitches()}.
1166     */
1167    long mAppSwitchesAllowedTime;
1168
1169    /**
1170     * This is set to true after the first switch after mAppSwitchesAllowedTime
1171     * is set; any switches after that will clear the time.
1172     */
1173    boolean mDidAppSwitch;
1174
1175    /**
1176     * Last time (in realtime) at which we checked for power usage.
1177     */
1178    long mLastPowerCheckRealtime;
1179
1180    /**
1181     * Last time (in uptime) at which we checked for power usage.
1182     */
1183    long mLastPowerCheckUptime;
1184
1185    /**
1186     * Set while we are wanting to sleep, to prevent any
1187     * activities from being started/resumed.
1188     */
1189    private boolean mSleeping = false;
1190
1191    /**
1192     * The process state used for processes that are running the top activities.
1193     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1194     */
1195    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1196
1197    /**
1198     * Set while we are running a voice interaction.  This overrides
1199     * sleeping while it is active.
1200     */
1201    private IVoiceInteractionSession mRunningVoice;
1202
1203    /**
1204     * For some direct access we need to power manager.
1205     */
1206    PowerManagerInternal mLocalPowerManager;
1207
1208    /**
1209     * We want to hold a wake lock while running a voice interaction session, since
1210     * this may happen with the screen off and we need to keep the CPU running to
1211     * be able to continue to interact with the user.
1212     */
1213    PowerManager.WakeLock mVoiceWakeLock;
1214
1215    /**
1216     * State of external calls telling us if the device is awake or asleep.
1217     */
1218    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1219
1220    /**
1221     * A list of tokens that cause the top activity to be put to sleep.
1222     * They are used by components that may hide and block interaction with underlying
1223     * activities.
1224     */
1225    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1226
1227    static final int LOCK_SCREEN_HIDDEN = 0;
1228    static final int LOCK_SCREEN_LEAVING = 1;
1229    static final int LOCK_SCREEN_SHOWN = 2;
1230    /**
1231     * State of external call telling us if the lock screen is shown.
1232     */
1233    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1234
1235    /**
1236     * Set if we are shutting down the system, similar to sleeping.
1237     */
1238    boolean mShuttingDown = false;
1239
1240    /**
1241     * Current sequence id for oom_adj computation traversal.
1242     */
1243    int mAdjSeq = 0;
1244
1245    /**
1246     * Current sequence id for process LRU updating.
1247     */
1248    int mLruSeq = 0;
1249
1250    /**
1251     * Keep track of the non-cached/empty process we last found, to help
1252     * determine how to distribute cached/empty processes next time.
1253     */
1254    int mNumNonCachedProcs = 0;
1255
1256    /**
1257     * Keep track of the number of cached hidden procs, to balance oom adj
1258     * distribution between those and empty procs.
1259     */
1260    int mNumCachedHiddenProcs = 0;
1261
1262    /**
1263     * Keep track of the number of service processes we last found, to
1264     * determine on the next iteration which should be B services.
1265     */
1266    int mNumServiceProcs = 0;
1267    int mNewNumAServiceProcs = 0;
1268    int mNewNumServiceProcs = 0;
1269
1270    /**
1271     * Allow the current computed overall memory level of the system to go down?
1272     * This is set to false when we are killing processes for reasons other than
1273     * memory management, so that the now smaller process list will not be taken as
1274     * an indication that memory is tighter.
1275     */
1276    boolean mAllowLowerMemLevel = false;
1277
1278    /**
1279     * The last computed memory level, for holding when we are in a state that
1280     * processes are going away for other reasons.
1281     */
1282    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1283
1284    /**
1285     * The last total number of process we have, to determine if changes actually look
1286     * like a shrinking number of process due to lower RAM.
1287     */
1288    int mLastNumProcesses;
1289
1290    /**
1291     * The uptime of the last time we performed idle maintenance.
1292     */
1293    long mLastIdleTime = SystemClock.uptimeMillis();
1294
1295    /**
1296     * Total time spent with RAM that has been added in the past since the last idle time.
1297     */
1298    long mLowRamTimeSinceLastIdle = 0;
1299
1300    /**
1301     * If RAM is currently low, when that horrible situation started.
1302     */
1303    long mLowRamStartTime = 0;
1304
1305    /**
1306     * For reporting to battery stats the current top application.
1307     */
1308    private String mCurResumedPackage = null;
1309    private int mCurResumedUid = -1;
1310
1311    /**
1312     * For reporting to battery stats the apps currently running foreground
1313     * service.  The ProcessMap is package/uid tuples; each of these contain
1314     * an array of the currently foreground processes.
1315     */
1316    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1317            = new ProcessMap<ArrayList<ProcessRecord>>();
1318
1319    /**
1320     * This is set if we had to do a delayed dexopt of an app before launching
1321     * it, to increase the ANR timeouts in that case.
1322     */
1323    boolean mDidDexOpt;
1324
1325    /**
1326     * Set if the systemServer made a call to enterSafeMode.
1327     */
1328    boolean mSafeMode;
1329
1330    /**
1331     * If true, we are running under a test environment so will sample PSS from processes
1332     * much more rapidly to try to collect better data when the tests are rapidly
1333     * running through apps.
1334     */
1335    boolean mTestPssMode = false;
1336
1337    String mDebugApp = null;
1338    boolean mWaitForDebugger = false;
1339    boolean mDebugTransient = false;
1340    String mOrigDebugApp = null;
1341    boolean mOrigWaitForDebugger = false;
1342    boolean mAlwaysFinishActivities = false;
1343    boolean mLenientBackgroundCheck = false;
1344    boolean mForceResizableActivities;
1345    boolean mSupportsMultiWindow;
1346    boolean mSupportsFreeformWindowManagement;
1347    boolean mSupportsPictureInPicture;
1348    Rect mDefaultPinnedStackBounds;
1349    IActivityController mController = null;
1350    boolean mControllerIsAMonkey = false;
1351    String mProfileApp = null;
1352    ProcessRecord mProfileProc = null;
1353    String mProfileFile;
1354    ParcelFileDescriptor mProfileFd;
1355    int mSamplingInterval = 0;
1356    boolean mAutoStopProfiler = false;
1357    int mProfileType = 0;
1358    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1359    String mMemWatchDumpProcName;
1360    String mMemWatchDumpFile;
1361    int mMemWatchDumpPid;
1362    int mMemWatchDumpUid;
1363    String mTrackAllocationApp = null;
1364    String mNativeDebuggingApp = null;
1365
1366    final long[] mTmpLong = new long[2];
1367
1368    static final class ProcessChangeItem {
1369        static final int CHANGE_ACTIVITIES = 1<<0;
1370        static final int CHANGE_PROCESS_STATE = 1<<1;
1371        int changes;
1372        int uid;
1373        int pid;
1374        int processState;
1375        boolean foregroundActivities;
1376    }
1377
1378    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1379    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1380
1381    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1382    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1383
1384    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1385    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1386
1387    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1388    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1389
1390    /**
1391     * Runtime CPU use collection thread.  This object's lock is used to
1392     * perform synchronization with the thread (notifying it to run).
1393     */
1394    final Thread mProcessCpuThread;
1395
1396    /**
1397     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1398     * Must acquire this object's lock when accessing it.
1399     * NOTE: this lock will be held while doing long operations (trawling
1400     * through all processes in /proc), so it should never be acquired by
1401     * any critical paths such as when holding the main activity manager lock.
1402     */
1403    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1404            MONITOR_THREAD_CPU_USAGE);
1405    final AtomicLong mLastCpuTime = new AtomicLong(0);
1406    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1407
1408    long mLastWriteTime = 0;
1409
1410    /**
1411     * Used to retain an update lock when the foreground activity is in
1412     * immersive mode.
1413     */
1414    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1415
1416    /**
1417     * Set to true after the system has finished booting.
1418     */
1419    boolean mBooted = false;
1420
1421    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1422    int mProcessLimitOverride = -1;
1423
1424    WindowManagerService mWindowManager;
1425    final ActivityThread mSystemThread;
1426
1427    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1428        final ProcessRecord mApp;
1429        final int mPid;
1430        final IApplicationThread mAppThread;
1431
1432        AppDeathRecipient(ProcessRecord app, int pid,
1433                IApplicationThread thread) {
1434            if (DEBUG_ALL) Slog.v(
1435                TAG, "New death recipient " + this
1436                + " for thread " + thread.asBinder());
1437            mApp = app;
1438            mPid = pid;
1439            mAppThread = thread;
1440        }
1441
1442        @Override
1443        public void binderDied() {
1444            if (DEBUG_ALL) Slog.v(
1445                TAG, "Death received in " + this
1446                + " for thread " + mAppThread.asBinder());
1447            synchronized(ActivityManagerService.this) {
1448                appDiedLocked(mApp, mPid, mAppThread, true);
1449            }
1450        }
1451    }
1452
1453    static final int SHOW_ERROR_UI_MSG = 1;
1454    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1455    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1456    static final int UPDATE_CONFIGURATION_MSG = 4;
1457    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1458    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1459    static final int SERVICE_TIMEOUT_MSG = 12;
1460    static final int UPDATE_TIME_ZONE = 13;
1461    static final int SHOW_UID_ERROR_UI_MSG = 14;
1462    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1463    static final int PROC_START_TIMEOUT_MSG = 20;
1464    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1465    static final int KILL_APPLICATION_MSG = 22;
1466    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1467    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1468    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1469    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1470    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1471    static final int CLEAR_DNS_CACHE_MSG = 28;
1472    static final int UPDATE_HTTP_PROXY_MSG = 29;
1473    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1474    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1475    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1476    static final int REPORT_MEM_USAGE_MSG = 33;
1477    static final int REPORT_USER_SWITCH_MSG = 34;
1478    static final int CONTINUE_USER_SWITCH_MSG = 35;
1479    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1480    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1481    static final int PERSIST_URI_GRANTS_MSG = 38;
1482    static final int REQUEST_ALL_PSS_MSG = 39;
1483    static final int START_PROFILES_MSG = 40;
1484    static final int UPDATE_TIME = 41;
1485    static final int SYSTEM_USER_START_MSG = 42;
1486    static final int SYSTEM_USER_CURRENT_MSG = 43;
1487    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1488    static final int FINISH_BOOTING_MSG = 45;
1489    static final int START_USER_SWITCH_UI_MSG = 46;
1490    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1491    static final int DISMISS_DIALOG_UI_MSG = 48;
1492    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1493    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1494    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1495    static final int DELETE_DUMPHEAP_MSG = 52;
1496    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1497    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1498    static final int REPORT_TIME_TRACKER_MSG = 55;
1499    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1500    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1501    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1502    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1503    static final int IDLE_UIDS_MSG = 60;
1504    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1505    static final int LOG_STACK_STATE = 62;
1506    static final int VR_MODE_CHANGE_MSG = 63;
1507    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1508    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1509    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1510    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1511    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1512    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1513
1514    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1515    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1516    static final int FIRST_COMPAT_MODE_MSG = 300;
1517    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1518
1519    static ServiceThread sKillThread = null;
1520    static KillHandler sKillHandler = null;
1521
1522    CompatModeDialog mCompatModeDialog;
1523    long mLastMemUsageReportTime = 0;
1524
1525    /**
1526     * Flag whether the current user is a "monkey", i.e. whether
1527     * the UI is driven by a UI automation tool.
1528     */
1529    private boolean mUserIsMonkey;
1530
1531    /** Flag whether the device has a Recents UI */
1532    boolean mHasRecents;
1533
1534    /** The dimensions of the thumbnails in the Recents UI. */
1535    int mThumbnailWidth;
1536    int mThumbnailHeight;
1537    float mFullscreenThumbnailScale;
1538
1539    final ServiceThread mHandlerThread;
1540    final MainHandler mHandler;
1541    final UiHandler mUiHandler;
1542
1543    PackageManagerInternal mPackageManagerInt;
1544
1545    // VoiceInteraction session ID that changes for each new request except when
1546    // being called for multiwindow assist in a single session.
1547    private int mViSessionId = 1000;
1548
1549    final class KillHandler extends Handler {
1550        static final int KILL_PROCESS_GROUP_MSG = 4000;
1551
1552        public KillHandler(Looper looper) {
1553            super(looper, null, true);
1554        }
1555
1556        @Override
1557        public void handleMessage(Message msg) {
1558            switch (msg.what) {
1559                case KILL_PROCESS_GROUP_MSG:
1560                {
1561                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1562                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1563                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1564                }
1565                break;
1566
1567                default:
1568                    super.handleMessage(msg);
1569            }
1570        }
1571    }
1572
1573    final class UiHandler extends Handler {
1574        public UiHandler() {
1575            super(com.android.server.UiThread.get().getLooper(), null, true);
1576        }
1577
1578        @Override
1579        public void handleMessage(Message msg) {
1580            switch (msg.what) {
1581            case SHOW_ERROR_UI_MSG: {
1582                mAppErrors.handleShowAppErrorUi(msg);
1583                ensureBootCompleted();
1584            } break;
1585            case SHOW_NOT_RESPONDING_UI_MSG: {
1586                mAppErrors.handleShowAnrUi(msg);
1587                ensureBootCompleted();
1588            } break;
1589            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1590                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1591                synchronized (ActivityManagerService.this) {
1592                    ProcessRecord proc = (ProcessRecord) data.get("app");
1593                    if (proc == null) {
1594                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1595                        break;
1596                    }
1597                    if (proc.crashDialog != null) {
1598                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1599                        return;
1600                    }
1601                    AppErrorResult res = (AppErrorResult) data.get("result");
1602                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1603                        Dialog d = new StrictModeViolationDialog(mContext,
1604                                ActivityManagerService.this, res, proc);
1605                        d.show();
1606                        proc.crashDialog = d;
1607                    } else {
1608                        // The device is asleep, so just pretend that the user
1609                        // saw a crash dialog and hit "force quit".
1610                        res.set(0);
1611                    }
1612                }
1613                ensureBootCompleted();
1614            } break;
1615            case SHOW_FACTORY_ERROR_UI_MSG: {
1616                Dialog d = new FactoryErrorDialog(
1617                    mContext, msg.getData().getCharSequence("msg"));
1618                d.show();
1619                ensureBootCompleted();
1620            } break;
1621            case WAIT_FOR_DEBUGGER_UI_MSG: {
1622                synchronized (ActivityManagerService.this) {
1623                    ProcessRecord app = (ProcessRecord)msg.obj;
1624                    if (msg.arg1 != 0) {
1625                        if (!app.waitedForDebugger) {
1626                            Dialog d = new AppWaitingForDebuggerDialog(
1627                                    ActivityManagerService.this,
1628                                    mContext, app);
1629                            app.waitDialog = d;
1630                            app.waitedForDebugger = true;
1631                            d.show();
1632                        }
1633                    } else {
1634                        if (app.waitDialog != null) {
1635                            app.waitDialog.dismiss();
1636                            app.waitDialog = null;
1637                        }
1638                    }
1639                }
1640            } break;
1641            case SHOW_UID_ERROR_UI_MSG: {
1642                if (mShowDialogs) {
1643                    AlertDialog d = new BaseErrorDialog(mContext);
1644                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1645                    d.setCancelable(false);
1646                    d.setTitle(mContext.getText(R.string.android_system_label));
1647                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1648                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1649                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1650                    d.show();
1651                }
1652            } break;
1653            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1654                if (mShowDialogs) {
1655                    AlertDialog d = new BaseErrorDialog(mContext);
1656                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1657                    d.setCancelable(false);
1658                    d.setTitle(mContext.getText(R.string.android_system_label));
1659                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1660                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1661                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1662                    d.show();
1663                }
1664            } break;
1665            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1666                synchronized (ActivityManagerService.this) {
1667                    ActivityRecord ar = (ActivityRecord) msg.obj;
1668                    if (mCompatModeDialog != null) {
1669                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1670                                ar.info.applicationInfo.packageName)) {
1671                            return;
1672                        }
1673                        mCompatModeDialog.dismiss();
1674                        mCompatModeDialog = null;
1675                    }
1676                    if (ar != null && false) {
1677                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1678                                ar.packageName)) {
1679                            int mode = mCompatModePackages.computeCompatModeLocked(
1680                                    ar.info.applicationInfo);
1681                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1682                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1683                                mCompatModeDialog = new CompatModeDialog(
1684                                        ActivityManagerService.this, mContext,
1685                                        ar.info.applicationInfo);
1686                                mCompatModeDialog.show();
1687                            }
1688                        }
1689                    }
1690                }
1691                break;
1692            }
1693            case START_USER_SWITCH_UI_MSG: {
1694                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1695                break;
1696            }
1697            case DISMISS_DIALOG_UI_MSG: {
1698                final Dialog d = (Dialog) msg.obj;
1699                d.dismiss();
1700                break;
1701            }
1702            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1703                dispatchProcessesChanged();
1704                break;
1705            }
1706            case DISPATCH_PROCESS_DIED_UI_MSG: {
1707                final int pid = msg.arg1;
1708                final int uid = msg.arg2;
1709                dispatchProcessDied(pid, uid);
1710                break;
1711            }
1712            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1713                dispatchUidsChanged();
1714            } break;
1715            }
1716        }
1717    }
1718
1719    final class MainHandler extends Handler {
1720        public MainHandler(Looper looper) {
1721            super(looper, null, true);
1722        }
1723
1724        @Override
1725        public void handleMessage(Message msg) {
1726            switch (msg.what) {
1727            case UPDATE_CONFIGURATION_MSG: {
1728                final ContentResolver resolver = mContext.getContentResolver();
1729                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1730                        msg.arg1);
1731            } break;
1732            case GC_BACKGROUND_PROCESSES_MSG: {
1733                synchronized (ActivityManagerService.this) {
1734                    performAppGcsIfAppropriateLocked();
1735                }
1736            } break;
1737            case SERVICE_TIMEOUT_MSG: {
1738                if (mDidDexOpt) {
1739                    mDidDexOpt = false;
1740                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1741                    nmsg.obj = msg.obj;
1742                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1743                    return;
1744                }
1745                mServices.serviceTimeout((ProcessRecord)msg.obj);
1746            } break;
1747            case UPDATE_TIME_ZONE: {
1748                synchronized (ActivityManagerService.this) {
1749                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1750                        ProcessRecord r = mLruProcesses.get(i);
1751                        if (r.thread != null) {
1752                            try {
1753                                r.thread.updateTimeZone();
1754                            } catch (RemoteException ex) {
1755                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1756                            }
1757                        }
1758                    }
1759                }
1760            } break;
1761            case CLEAR_DNS_CACHE_MSG: {
1762                synchronized (ActivityManagerService.this) {
1763                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1764                        ProcessRecord r = mLruProcesses.get(i);
1765                        if (r.thread != null) {
1766                            try {
1767                                r.thread.clearDnsCache();
1768                            } catch (RemoteException ex) {
1769                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1770                            }
1771                        }
1772                    }
1773                }
1774            } break;
1775            case UPDATE_HTTP_PROXY_MSG: {
1776                ProxyInfo proxy = (ProxyInfo)msg.obj;
1777                String host = "";
1778                String port = "";
1779                String exclList = "";
1780                Uri pacFileUrl = Uri.EMPTY;
1781                if (proxy != null) {
1782                    host = proxy.getHost();
1783                    port = Integer.toString(proxy.getPort());
1784                    exclList = proxy.getExclusionListAsString();
1785                    pacFileUrl = proxy.getPacFileUrl();
1786                }
1787                synchronized (ActivityManagerService.this) {
1788                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1789                        ProcessRecord r = mLruProcesses.get(i);
1790                        if (r.thread != null) {
1791                            try {
1792                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1793                            } catch (RemoteException ex) {
1794                                Slog.w(TAG, "Failed to update http proxy for: " +
1795                                        r.info.processName);
1796                            }
1797                        }
1798                    }
1799                }
1800            } break;
1801            case PROC_START_TIMEOUT_MSG: {
1802                if (mDidDexOpt) {
1803                    mDidDexOpt = false;
1804                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1805                    nmsg.obj = msg.obj;
1806                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1807                    return;
1808                }
1809                ProcessRecord app = (ProcessRecord)msg.obj;
1810                synchronized (ActivityManagerService.this) {
1811                    processStartTimedOutLocked(app);
1812                }
1813            } break;
1814            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1815                ProcessRecord app = (ProcessRecord)msg.obj;
1816                synchronized (ActivityManagerService.this) {
1817                    processContentProviderPublishTimedOutLocked(app);
1818                }
1819            } break;
1820            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1821                synchronized (ActivityManagerService.this) {
1822                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1823                }
1824            } break;
1825            case KILL_APPLICATION_MSG: {
1826                synchronized (ActivityManagerService.this) {
1827                    int appid = msg.arg1;
1828                    boolean restart = (msg.arg2 == 1);
1829                    Bundle bundle = (Bundle)msg.obj;
1830                    String pkg = bundle.getString("pkg");
1831                    String reason = bundle.getString("reason");
1832                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1833                            false, UserHandle.USER_ALL, reason);
1834                }
1835            } break;
1836            case FINALIZE_PENDING_INTENT_MSG: {
1837                ((PendingIntentRecord)msg.obj).completeFinalize();
1838            } break;
1839            case POST_HEAVY_NOTIFICATION_MSG: {
1840                INotificationManager inm = NotificationManager.getService();
1841                if (inm == null) {
1842                    return;
1843                }
1844
1845                ActivityRecord root = (ActivityRecord)msg.obj;
1846                ProcessRecord process = root.app;
1847                if (process == null) {
1848                    return;
1849                }
1850
1851                try {
1852                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1853                    String text = mContext.getString(R.string.heavy_weight_notification,
1854                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1855                    Notification notification = new Notification.Builder(context)
1856                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1857                            .setWhen(0)
1858                            .setOngoing(true)
1859                            .setTicker(text)
1860                            .setColor(mContext.getColor(
1861                                    com.android.internal.R.color.system_notification_accent_color))
1862                            .setContentTitle(text)
1863                            .setContentText(
1864                                    mContext.getText(R.string.heavy_weight_notification_detail))
1865                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1866                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1867                                    new UserHandle(root.userId)))
1868                            .build();
1869                    try {
1870                        int[] outId = new int[1];
1871                        inm.enqueueNotificationWithTag("android", "android", null,
1872                                R.string.heavy_weight_notification,
1873                                notification, outId, root.userId);
1874                    } catch (RuntimeException e) {
1875                        Slog.w(ActivityManagerService.TAG,
1876                                "Error showing notification for heavy-weight app", e);
1877                    } catch (RemoteException e) {
1878                    }
1879                } catch (NameNotFoundException e) {
1880                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1881                }
1882            } break;
1883            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1884                INotificationManager inm = NotificationManager.getService();
1885                if (inm == null) {
1886                    return;
1887                }
1888                try {
1889                    inm.cancelNotificationWithTag("android", null,
1890                            R.string.heavy_weight_notification,  msg.arg1);
1891                } catch (RuntimeException e) {
1892                    Slog.w(ActivityManagerService.TAG,
1893                            "Error canceling notification for service", e);
1894                } catch (RemoteException e) {
1895                }
1896            } break;
1897            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1898                synchronized (ActivityManagerService.this) {
1899                    checkExcessivePowerUsageLocked(true);
1900                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1901                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1902                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1903                }
1904            } break;
1905            case REPORT_MEM_USAGE_MSG: {
1906                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1907                Thread thread = new Thread() {
1908                    @Override public void run() {
1909                        reportMemUsage(memInfos);
1910                    }
1911                };
1912                thread.start();
1913                break;
1914            }
1915            case REPORT_USER_SWITCH_MSG: {
1916                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1917                break;
1918            }
1919            case CONTINUE_USER_SWITCH_MSG: {
1920                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1921                break;
1922            }
1923            case USER_SWITCH_TIMEOUT_MSG: {
1924                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1925                break;
1926            }
1927            case IMMERSIVE_MODE_LOCK_MSG: {
1928                final boolean nextState = (msg.arg1 != 0);
1929                if (mUpdateLock.isHeld() != nextState) {
1930                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1931                            "Applying new update lock state '" + nextState
1932                            + "' for " + (ActivityRecord)msg.obj);
1933                    if (nextState) {
1934                        mUpdateLock.acquire();
1935                    } else {
1936                        mUpdateLock.release();
1937                    }
1938                }
1939                break;
1940            }
1941            case PERSIST_URI_GRANTS_MSG: {
1942                writeGrantedUriPermissions();
1943                break;
1944            }
1945            case REQUEST_ALL_PSS_MSG: {
1946                synchronized (ActivityManagerService.this) {
1947                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1948                }
1949                break;
1950            }
1951            case START_PROFILES_MSG: {
1952                synchronized (ActivityManagerService.this) {
1953                    mUserController.startProfilesLocked();
1954                }
1955                break;
1956            }
1957            case UPDATE_TIME: {
1958                synchronized (ActivityManagerService.this) {
1959                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1960                        ProcessRecord r = mLruProcesses.get(i);
1961                        if (r.thread != null) {
1962                            try {
1963                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1964                            } catch (RemoteException ex) {
1965                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1966                            }
1967                        }
1968                    }
1969                }
1970                break;
1971            }
1972            case SYSTEM_USER_START_MSG: {
1973                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1974                        Integer.toString(msg.arg1), msg.arg1);
1975                mSystemServiceManager.startUser(msg.arg1);
1976                break;
1977            }
1978            case SYSTEM_USER_UNLOCK_MSG: {
1979                final int userId = msg.arg1;
1980                mSystemServiceManager.unlockUser(userId);
1981                synchronized (ActivityManagerService.this) {
1982                    mRecentTasks.loadUserRecentsLocked(userId);
1983                }
1984                if (userId == UserHandle.USER_SYSTEM) {
1985                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
1986                }
1987                installEncryptionUnawareProviders(userId);
1988                mUserController.finishUserUnlocked((UserState) msg.obj);
1989                break;
1990            }
1991            case SYSTEM_USER_CURRENT_MSG: {
1992                mBatteryStatsService.noteEvent(
1993                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1994                        Integer.toString(msg.arg2), msg.arg2);
1995                mBatteryStatsService.noteEvent(
1996                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1997                        Integer.toString(msg.arg1), msg.arg1);
1998                mSystemServiceManager.switchUser(msg.arg1);
1999                break;
2000            }
2001            case ENTER_ANIMATION_COMPLETE_MSG: {
2002                synchronized (ActivityManagerService.this) {
2003                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2004                    if (r != null && r.app != null && r.app.thread != null) {
2005                        try {
2006                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2007                        } catch (RemoteException e) {
2008                        }
2009                    }
2010                }
2011                break;
2012            }
2013            case FINISH_BOOTING_MSG: {
2014                if (msg.arg1 != 0) {
2015                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2016                    finishBooting();
2017                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2018                }
2019                if (msg.arg2 != 0) {
2020                    enableScreenAfterBoot();
2021                }
2022                break;
2023            }
2024            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2025                try {
2026                    Locale l = (Locale) msg.obj;
2027                    IBinder service = ServiceManager.getService("mount");
2028                    IMountService mountService = IMountService.Stub.asInterface(service);
2029                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2030                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2031                } catch (RemoteException e) {
2032                    Log.e(TAG, "Error storing locale for decryption UI", e);
2033                }
2034                break;
2035            }
2036            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2037                synchronized (ActivityManagerService.this) {
2038                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2039                        try {
2040                            // Make a one-way callback to the listener
2041                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2042                        } catch (RemoteException e){
2043                            // Handled by the RemoteCallbackList
2044                        }
2045                    }
2046                    mTaskStackListeners.finishBroadcast();
2047                }
2048                break;
2049            }
2050            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2051                synchronized (ActivityManagerService.this) {
2052                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2053                        try {
2054                            // Make a one-way callback to the listener
2055                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2056                        } catch (RemoteException e){
2057                            // Handled by the RemoteCallbackList
2058                        }
2059                    }
2060                    mTaskStackListeners.finishBroadcast();
2061                }
2062                break;
2063            }
2064            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2065                synchronized (ActivityManagerService.this) {
2066                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2067                        try {
2068                            // Make a one-way callback to the listener
2069                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2070                        } catch (RemoteException e){
2071                            // Handled by the RemoteCallbackList
2072                        }
2073                    }
2074                    mTaskStackListeners.finishBroadcast();
2075                }
2076                break;
2077            }
2078            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2079                synchronized (ActivityManagerService.this) {
2080                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2081                        try {
2082                            // Make a one-way callback to the listener
2083                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2084                        } catch (RemoteException e){
2085                            // Handled by the RemoteCallbackList
2086                        }
2087                    }
2088                    mTaskStackListeners.finishBroadcast();
2089                }
2090                break;
2091            }
2092            case NOTIFY_FORCED_RESIZABLE_MSG: {
2093                synchronized (ActivityManagerService.this) {
2094                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2095                        try {
2096                            // Make a one-way callback to the listener
2097                            mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2098                                    (String) msg.obj, msg.arg1);
2099                        } catch (RemoteException e){
2100                            // Handled by the RemoteCallbackList
2101                        }
2102                    }
2103                    mTaskStackListeners.finishBroadcast();
2104                }
2105                break;
2106            }
2107                case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2108                    synchronized (ActivityManagerService.this) {
2109                        for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2110                            try {
2111                                // Make a one-way callback to the listener
2112                                mTaskStackListeners.getBroadcastItem(i)
2113                                        .onActivityDismissingDockedStack();
2114                            } catch (RemoteException e){
2115                                // Handled by the RemoteCallbackList
2116                            }
2117                        }
2118                        mTaskStackListeners.finishBroadcast();
2119                    }
2120                    break;
2121                }
2122            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2123                final int uid = msg.arg1;
2124                final byte[] firstPacket = (byte[]) msg.obj;
2125
2126                synchronized (mPidsSelfLocked) {
2127                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2128                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2129                        if (p.uid == uid) {
2130                            try {
2131                                p.thread.notifyCleartextNetwork(firstPacket);
2132                            } catch (RemoteException ignored) {
2133                            }
2134                        }
2135                    }
2136                }
2137                break;
2138            }
2139            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2140                final String procName;
2141                final int uid;
2142                final long memLimit;
2143                final String reportPackage;
2144                synchronized (ActivityManagerService.this) {
2145                    procName = mMemWatchDumpProcName;
2146                    uid = mMemWatchDumpUid;
2147                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2148                    if (val == null) {
2149                        val = mMemWatchProcesses.get(procName, 0);
2150                    }
2151                    if (val != null) {
2152                        memLimit = val.first;
2153                        reportPackage = val.second;
2154                    } else {
2155                        memLimit = 0;
2156                        reportPackage = null;
2157                    }
2158                }
2159                if (procName == null) {
2160                    return;
2161                }
2162
2163                if (DEBUG_PSS) Slog.d(TAG_PSS,
2164                        "Showing dump heap notification from " + procName + "/" + uid);
2165
2166                INotificationManager inm = NotificationManager.getService();
2167                if (inm == null) {
2168                    return;
2169                }
2170
2171                String text = mContext.getString(R.string.dump_heap_notification, procName);
2172
2173
2174                Intent deleteIntent = new Intent();
2175                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2176                Intent intent = new Intent();
2177                intent.setClassName("android", DumpHeapActivity.class.getName());
2178                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2179                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2180                if (reportPackage != null) {
2181                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2182                }
2183                int userId = UserHandle.getUserId(uid);
2184                Notification notification = new Notification.Builder(mContext)
2185                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2186                        .setWhen(0)
2187                        .setOngoing(true)
2188                        .setAutoCancel(true)
2189                        .setTicker(text)
2190                        .setColor(mContext.getColor(
2191                                com.android.internal.R.color.system_notification_accent_color))
2192                        .setContentTitle(text)
2193                        .setContentText(
2194                                mContext.getText(R.string.dump_heap_notification_detail))
2195                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2196                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2197                                new UserHandle(userId)))
2198                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2199                                deleteIntent, 0, UserHandle.SYSTEM))
2200                        .build();
2201
2202                try {
2203                    int[] outId = new int[1];
2204                    inm.enqueueNotificationWithTag("android", "android", null,
2205                            R.string.dump_heap_notification,
2206                            notification, outId, userId);
2207                } catch (RuntimeException e) {
2208                    Slog.w(ActivityManagerService.TAG,
2209                            "Error showing notification for dump heap", e);
2210                } catch (RemoteException e) {
2211                }
2212            } break;
2213            case DELETE_DUMPHEAP_MSG: {
2214                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2215                        DumpHeapActivity.JAVA_URI,
2216                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2217                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2218                        UserHandle.myUserId());
2219                synchronized (ActivityManagerService.this) {
2220                    mMemWatchDumpFile = null;
2221                    mMemWatchDumpProcName = null;
2222                    mMemWatchDumpPid = -1;
2223                    mMemWatchDumpUid = -1;
2224                }
2225            } break;
2226            case FOREGROUND_PROFILE_CHANGED_MSG: {
2227                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2228            } break;
2229            case REPORT_TIME_TRACKER_MSG: {
2230                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2231                tracker.deliverResult(mContext);
2232            } break;
2233            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2234                mUserController.dispatchUserSwitchComplete(msg.arg1);
2235            } break;
2236            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2237                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2238                try {
2239                    connection.shutdown();
2240                } catch (RemoteException e) {
2241                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2242                }
2243                // Only a UiAutomation can set this flag and now that
2244                // it is finished we make sure it is reset to its default.
2245                mUserIsMonkey = false;
2246            } break;
2247            case APP_BOOST_DEACTIVATE_MSG: {
2248                synchronized(ActivityManagerService.this) {
2249                    if (mIsBoosted) {
2250                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2251                            nativeMigrateFromBoost();
2252                            mIsBoosted = false;
2253                            mBoostStartTime = 0;
2254                        } else {
2255                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2256                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2257                        }
2258                    }
2259                }
2260            } break;
2261            case IDLE_UIDS_MSG: {
2262                idleUids();
2263            } break;
2264            case LOG_STACK_STATE: {
2265                synchronized (ActivityManagerService.this) {
2266                    mStackSupervisor.logStackState();
2267                }
2268            } break;
2269            case VR_MODE_CHANGE_MSG: {
2270                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2271                final ActivityRecord r = (ActivityRecord) msg.obj;
2272                boolean vrMode;
2273                ComponentName requestedPackage;
2274                ComponentName callingPackage;
2275                int userId;
2276                synchronized (ActivityManagerService.this) {
2277                    vrMode = r.requestedVrComponent != null;
2278                    requestedPackage = r.requestedVrComponent;
2279                    userId = r.userId;
2280                    callingPackage = r.info.getComponentName();
2281                    if (mInVrMode != vrMode) {
2282                        mInVrMode = vrMode;
2283                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2284                    }
2285                }
2286                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2287            } break;
2288            case VR_MODE_APPLY_IF_NEEDED_MSG: {
2289                final ActivityRecord r = (ActivityRecord) msg.obj;
2290                final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2291                if (needsVrMode) {
2292                    VrManagerInternal vrService =
2293                            LocalServices.getService(VrManagerInternal.class);
2294                    boolean enable = msg.arg1 == 1;
2295                    vrService.setVrMode(enable, r.requestedVrComponent, r.userId,
2296                            r.info.getComponentName());
2297                }
2298            } break;
2299            }
2300        }
2301    };
2302
2303    static final int COLLECT_PSS_BG_MSG = 1;
2304
2305    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2306        @Override
2307        public void handleMessage(Message msg) {
2308            switch (msg.what) {
2309            case COLLECT_PSS_BG_MSG: {
2310                long start = SystemClock.uptimeMillis();
2311                MemInfoReader memInfo = null;
2312                synchronized (ActivityManagerService.this) {
2313                    if (mFullPssPending) {
2314                        mFullPssPending = false;
2315                        memInfo = new MemInfoReader();
2316                    }
2317                }
2318                if (memInfo != null) {
2319                    updateCpuStatsNow();
2320                    long nativeTotalPss = 0;
2321                    synchronized (mProcessCpuTracker) {
2322                        final int N = mProcessCpuTracker.countStats();
2323                        for (int j=0; j<N; j++) {
2324                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2325                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2326                                // This is definitely an application process; skip it.
2327                                continue;
2328                            }
2329                            synchronized (mPidsSelfLocked) {
2330                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2331                                    // This is one of our own processes; skip it.
2332                                    continue;
2333                                }
2334                            }
2335                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2336                        }
2337                    }
2338                    memInfo.readMemInfo();
2339                    synchronized (ActivityManagerService.this) {
2340                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2341                                + (SystemClock.uptimeMillis()-start) + "ms");
2342                        final long cachedKb = memInfo.getCachedSizeKb();
2343                        final long freeKb = memInfo.getFreeSizeKb();
2344                        final long zramKb = memInfo.getZramTotalSizeKb();
2345                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2346                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2347                                kernelKb*1024, nativeTotalPss*1024);
2348                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2349                                nativeTotalPss);
2350                    }
2351                }
2352
2353                int num = 0;
2354                long[] tmp = new long[2];
2355                do {
2356                    ProcessRecord proc;
2357                    int procState;
2358                    int pid;
2359                    long lastPssTime;
2360                    synchronized (ActivityManagerService.this) {
2361                        if (mPendingPssProcesses.size() <= 0) {
2362                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2363                                    "Collected PSS of " + num + " processes in "
2364                                    + (SystemClock.uptimeMillis() - start) + "ms");
2365                            mPendingPssProcesses.clear();
2366                            return;
2367                        }
2368                        proc = mPendingPssProcesses.remove(0);
2369                        procState = proc.pssProcState;
2370                        lastPssTime = proc.lastPssTime;
2371                        if (proc.thread != null && procState == proc.setProcState
2372                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2373                                        < SystemClock.uptimeMillis()) {
2374                            pid = proc.pid;
2375                        } else {
2376                            proc = null;
2377                            pid = 0;
2378                        }
2379                    }
2380                    if (proc != null) {
2381                        long pss = Debug.getPss(pid, tmp, null);
2382                        synchronized (ActivityManagerService.this) {
2383                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2384                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2385                                num++;
2386                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2387                                        SystemClock.uptimeMillis());
2388                            }
2389                        }
2390                    }
2391                } while (true);
2392            }
2393            }
2394        }
2395    };
2396
2397    public void setSystemProcess() {
2398        try {
2399            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2400            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2401            ServiceManager.addService("meminfo", new MemBinder(this));
2402            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2403            ServiceManager.addService("dbinfo", new DbBinder(this));
2404            if (MONITOR_CPU_USAGE) {
2405                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2406            }
2407            ServiceManager.addService("permission", new PermissionController(this));
2408            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2409
2410            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2411                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2412            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2413
2414            synchronized (this) {
2415                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2416                app.persistent = true;
2417                app.pid = MY_PID;
2418                app.maxAdj = ProcessList.SYSTEM_ADJ;
2419                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2420                synchronized (mPidsSelfLocked) {
2421                    mPidsSelfLocked.put(app.pid, app);
2422                }
2423                updateLruProcessLocked(app, false, null);
2424                updateOomAdjLocked();
2425            }
2426        } catch (PackageManager.NameNotFoundException e) {
2427            throw new RuntimeException(
2428                    "Unable to find android system package", e);
2429        }
2430    }
2431
2432    public void setWindowManager(WindowManagerService wm) {
2433        mWindowManager = wm;
2434        mStackSupervisor.setWindowManager(wm);
2435        mActivityStarter.setWindowManager(wm);
2436    }
2437
2438    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2439        mUsageStatsService = usageStatsManager;
2440    }
2441
2442    public void startObservingNativeCrashes() {
2443        final NativeCrashListener ncl = new NativeCrashListener(this);
2444        ncl.start();
2445    }
2446
2447    public IAppOpsService getAppOpsService() {
2448        return mAppOpsService;
2449    }
2450
2451    static class MemBinder extends Binder {
2452        ActivityManagerService mActivityManagerService;
2453        MemBinder(ActivityManagerService activityManagerService) {
2454            mActivityManagerService = activityManagerService;
2455        }
2456
2457        @Override
2458        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2459            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2460                    != PackageManager.PERMISSION_GRANTED) {
2461                pw.println("Permission Denial: can't dump meminfo from from pid="
2462                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2463                        + " without permission " + android.Manifest.permission.DUMP);
2464                return;
2465            }
2466
2467            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2468        }
2469    }
2470
2471    static class GraphicsBinder extends Binder {
2472        ActivityManagerService mActivityManagerService;
2473        GraphicsBinder(ActivityManagerService activityManagerService) {
2474            mActivityManagerService = activityManagerService;
2475        }
2476
2477        @Override
2478        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2479            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2480                    != PackageManager.PERMISSION_GRANTED) {
2481                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2482                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2483                        + " without permission " + android.Manifest.permission.DUMP);
2484                return;
2485            }
2486
2487            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2488        }
2489    }
2490
2491    static class DbBinder extends Binder {
2492        ActivityManagerService mActivityManagerService;
2493        DbBinder(ActivityManagerService activityManagerService) {
2494            mActivityManagerService = activityManagerService;
2495        }
2496
2497        @Override
2498        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2499            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2500                    != PackageManager.PERMISSION_GRANTED) {
2501                pw.println("Permission Denial: can't dump dbinfo from from pid="
2502                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2503                        + " without permission " + android.Manifest.permission.DUMP);
2504                return;
2505            }
2506
2507            mActivityManagerService.dumpDbInfo(fd, pw, args);
2508        }
2509    }
2510
2511    static class CpuBinder extends Binder {
2512        ActivityManagerService mActivityManagerService;
2513        CpuBinder(ActivityManagerService activityManagerService) {
2514            mActivityManagerService = activityManagerService;
2515        }
2516
2517        @Override
2518        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2519            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2520                    != PackageManager.PERMISSION_GRANTED) {
2521                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2522                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2523                        + " without permission " + android.Manifest.permission.DUMP);
2524                return;
2525            }
2526
2527            synchronized (mActivityManagerService.mProcessCpuTracker) {
2528                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2529                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2530                        SystemClock.uptimeMillis()));
2531            }
2532        }
2533    }
2534
2535    public static final class Lifecycle extends SystemService {
2536        private final ActivityManagerService mService;
2537
2538        public Lifecycle(Context context) {
2539            super(context);
2540            mService = new ActivityManagerService(context);
2541        }
2542
2543        @Override
2544        public void onStart() {
2545            mService.start();
2546        }
2547
2548        public ActivityManagerService getService() {
2549            return mService;
2550        }
2551    }
2552
2553    // Note: This method is invoked on the main thread but may need to attach various
2554    // handlers to other threads.  So take care to be explicit about the looper.
2555    public ActivityManagerService(Context systemContext) {
2556        mContext = systemContext;
2557        mFactoryTest = FactoryTest.getMode();
2558        mSystemThread = ActivityThread.currentActivityThread();
2559
2560        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2561
2562        mHandlerThread = new ServiceThread(TAG,
2563                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2564        mHandlerThread.start();
2565        mHandler = new MainHandler(mHandlerThread.getLooper());
2566        mUiHandler = new UiHandler();
2567
2568        /* static; one-time init here */
2569        if (sKillHandler == null) {
2570            sKillThread = new ServiceThread(TAG + ":kill",
2571                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2572            sKillThread.start();
2573            sKillHandler = new KillHandler(sKillThread.getLooper());
2574        }
2575
2576        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2577                "foreground", BROADCAST_FG_TIMEOUT, false);
2578        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2579                "background", BROADCAST_BG_TIMEOUT, true);
2580        mBroadcastQueues[0] = mFgBroadcastQueue;
2581        mBroadcastQueues[1] = mBgBroadcastQueue;
2582
2583        mServices = new ActiveServices(this);
2584        mProviderMap = new ProviderMap(this);
2585        mAppErrors = new AppErrors(mContext, this);
2586
2587        // TODO: Move creation of battery stats service outside of activity manager service.
2588        File dataDir = Environment.getDataDirectory();
2589        File systemDir = new File(dataDir, "system");
2590        systemDir.mkdirs();
2591        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2592        mBatteryStatsService.getActiveStatistics().readLocked();
2593        mBatteryStatsService.scheduleWriteToDisk();
2594        mOnBattery = DEBUG_POWER ? true
2595                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2596        mBatteryStatsService.getActiveStatistics().setCallback(this);
2597
2598        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2599
2600        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2601        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2602                new IAppOpsCallback.Stub() {
2603                    @Override public void opChanged(int op, int uid, String packageName) {
2604                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2605                            if (mAppOpsService.checkOperation(op, uid, packageName)
2606                                    != AppOpsManager.MODE_ALLOWED) {
2607                                runInBackgroundDisabled(uid);
2608                            }
2609                        }
2610                    }
2611                });
2612
2613        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2614
2615        mUserController = new UserController(this);
2616
2617        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2618            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2619
2620        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2621
2622        mConfiguration.setToDefaults();
2623        mConfiguration.setLocales(LocaleList.getDefault());
2624
2625        mConfigurationSeq = mConfiguration.seq = 1;
2626        mProcessCpuTracker.init();
2627
2628        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2629        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2630        mStackSupervisor = new ActivityStackSupervisor(this);
2631        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2632        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2633
2634        mProcessCpuThread = new Thread("CpuTracker") {
2635            @Override
2636            public void run() {
2637                while (true) {
2638                    try {
2639                        try {
2640                            synchronized(this) {
2641                                final long now = SystemClock.uptimeMillis();
2642                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2643                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2644                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2645                                //        + ", write delay=" + nextWriteDelay);
2646                                if (nextWriteDelay < nextCpuDelay) {
2647                                    nextCpuDelay = nextWriteDelay;
2648                                }
2649                                if (nextCpuDelay > 0) {
2650                                    mProcessCpuMutexFree.set(true);
2651                                    this.wait(nextCpuDelay);
2652                                }
2653                            }
2654                        } catch (InterruptedException e) {
2655                        }
2656                        updateCpuStatsNow();
2657                    } catch (Exception e) {
2658                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2659                    }
2660                }
2661            }
2662        };
2663
2664        Watchdog.getInstance().addMonitor(this);
2665        Watchdog.getInstance().addThread(mHandler);
2666    }
2667
2668    public void setSystemServiceManager(SystemServiceManager mgr) {
2669        mSystemServiceManager = mgr;
2670    }
2671
2672    public void setInstaller(Installer installer) {
2673        mInstaller = installer;
2674    }
2675
2676    private void start() {
2677        Process.removeAllProcessGroups();
2678        mProcessCpuThread.start();
2679
2680        mBatteryStatsService.publish(mContext);
2681        mAppOpsService.publish(mContext);
2682        Slog.d("AppOps", "AppOpsService published");
2683        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2684    }
2685
2686    void onUserStoppedLocked(int userId) {
2687        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2688    }
2689
2690    public void initPowerManagement() {
2691        mStackSupervisor.initPowerManagement();
2692        mBatteryStatsService.initPowerManagement();
2693        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2694        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2695        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2696        mVoiceWakeLock.setReferenceCounted(false);
2697    }
2698
2699    @Override
2700    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2701            throws RemoteException {
2702        if (code == SYSPROPS_TRANSACTION) {
2703            // We need to tell all apps about the system property change.
2704            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2705            synchronized(this) {
2706                final int NP = mProcessNames.getMap().size();
2707                for (int ip=0; ip<NP; ip++) {
2708                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2709                    final int NA = apps.size();
2710                    for (int ia=0; ia<NA; ia++) {
2711                        ProcessRecord app = apps.valueAt(ia);
2712                        if (app.thread != null) {
2713                            procs.add(app.thread.asBinder());
2714                        }
2715                    }
2716                }
2717            }
2718
2719            int N = procs.size();
2720            for (int i=0; i<N; i++) {
2721                Parcel data2 = Parcel.obtain();
2722                try {
2723                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2724                } catch (RemoteException e) {
2725                }
2726                data2.recycle();
2727            }
2728        }
2729        try {
2730            return super.onTransact(code, data, reply, flags);
2731        } catch (RuntimeException e) {
2732            // The activity manager only throws security exceptions, so let's
2733            // log all others.
2734            if (!(e instanceof SecurityException)) {
2735                Slog.wtf(TAG, "Activity Manager Crash", e);
2736            }
2737            throw e;
2738        }
2739    }
2740
2741    void updateCpuStats() {
2742        final long now = SystemClock.uptimeMillis();
2743        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2744            return;
2745        }
2746        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2747            synchronized (mProcessCpuThread) {
2748                mProcessCpuThread.notify();
2749            }
2750        }
2751    }
2752
2753    void updateCpuStatsNow() {
2754        synchronized (mProcessCpuTracker) {
2755            mProcessCpuMutexFree.set(false);
2756            final long now = SystemClock.uptimeMillis();
2757            boolean haveNewCpuStats = false;
2758
2759            if (MONITOR_CPU_USAGE &&
2760                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2761                mLastCpuTime.set(now);
2762                mProcessCpuTracker.update();
2763                if (mProcessCpuTracker.hasGoodLastStats()) {
2764                    haveNewCpuStats = true;
2765                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2766                    //Slog.i(TAG, "Total CPU usage: "
2767                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2768
2769                    // Slog the cpu usage if the property is set.
2770                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2771                        int user = mProcessCpuTracker.getLastUserTime();
2772                        int system = mProcessCpuTracker.getLastSystemTime();
2773                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2774                        int irq = mProcessCpuTracker.getLastIrqTime();
2775                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2776                        int idle = mProcessCpuTracker.getLastIdleTime();
2777
2778                        int total = user + system + iowait + irq + softIrq + idle;
2779                        if (total == 0) total = 1;
2780
2781                        EventLog.writeEvent(EventLogTags.CPU,
2782                                ((user+system+iowait+irq+softIrq) * 100) / total,
2783                                (user * 100) / total,
2784                                (system * 100) / total,
2785                                (iowait * 100) / total,
2786                                (irq * 100) / total,
2787                                (softIrq * 100) / total);
2788                    }
2789                }
2790            }
2791
2792            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2793            synchronized(bstats) {
2794                synchronized(mPidsSelfLocked) {
2795                    if (haveNewCpuStats) {
2796                        if (bstats.startAddingCpuLocked()) {
2797                            int totalUTime = 0;
2798                            int totalSTime = 0;
2799                            final int N = mProcessCpuTracker.countStats();
2800                            for (int i=0; i<N; i++) {
2801                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2802                                if (!st.working) {
2803                                    continue;
2804                                }
2805                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2806                                totalUTime += st.rel_utime;
2807                                totalSTime += st.rel_stime;
2808                                if (pr != null) {
2809                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2810                                    if (ps == null || !ps.isActive()) {
2811                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2812                                                pr.info.uid, pr.processName);
2813                                    }
2814                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2815                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2816                                } else {
2817                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2818                                    if (ps == null || !ps.isActive()) {
2819                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2820                                                bstats.mapUid(st.uid), st.name);
2821                                    }
2822                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2823                                }
2824                            }
2825                            final int userTime = mProcessCpuTracker.getLastUserTime();
2826                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2827                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2828                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2829                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2830                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2831                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2832                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2833                        }
2834                    }
2835                }
2836
2837                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2838                    mLastWriteTime = now;
2839                    mBatteryStatsService.scheduleWriteToDisk();
2840                }
2841            }
2842        }
2843    }
2844
2845    @Override
2846    public void batteryNeedsCpuUpdate() {
2847        updateCpuStatsNow();
2848    }
2849
2850    @Override
2851    public void batteryPowerChanged(boolean onBattery) {
2852        // When plugging in, update the CPU stats first before changing
2853        // the plug state.
2854        updateCpuStatsNow();
2855        synchronized (this) {
2856            synchronized(mPidsSelfLocked) {
2857                mOnBattery = DEBUG_POWER ? true : onBattery;
2858            }
2859        }
2860    }
2861
2862    @Override
2863    public void batterySendBroadcast(Intent intent) {
2864        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2865                AppOpsManager.OP_NONE, null, false, false,
2866                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2867    }
2868
2869    /**
2870     * Initialize the application bind args. These are passed to each
2871     * process when the bindApplication() IPC is sent to the process. They're
2872     * lazily setup to make sure the services are running when they're asked for.
2873     */
2874    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2875        if (mAppBindArgs == null) {
2876            mAppBindArgs = new HashMap<>();
2877
2878            // Isolated processes won't get this optimization, so that we don't
2879            // violate the rules about which services they have access to.
2880            if (!isolated) {
2881                // Setup the application init args
2882                mAppBindArgs.put("package", ServiceManager.getService("package"));
2883                mAppBindArgs.put("window", ServiceManager.getService("window"));
2884                mAppBindArgs.put(Context.ALARM_SERVICE,
2885                        ServiceManager.getService(Context.ALARM_SERVICE));
2886            }
2887        }
2888        return mAppBindArgs;
2889    }
2890
2891    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2892        if (r == null || mFocusedActivity == r) {
2893            return false;
2894        }
2895
2896        if (!r.isFocusable()) {
2897            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2898            return false;
2899        }
2900
2901        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2902
2903        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2904        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2905                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2906        mDoingSetFocusedActivity = true;
2907
2908        final ActivityRecord last = mFocusedActivity;
2909        mFocusedActivity = r;
2910        if (r.task.isApplicationTask()) {
2911            if (mCurAppTimeTracker != r.appTimeTracker) {
2912                // We are switching app tracking.  Complete the current one.
2913                if (mCurAppTimeTracker != null) {
2914                    mCurAppTimeTracker.stop();
2915                    mHandler.obtainMessage(
2916                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2917                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2918                    mCurAppTimeTracker = null;
2919                }
2920                if (r.appTimeTracker != null) {
2921                    mCurAppTimeTracker = r.appTimeTracker;
2922                    startTimeTrackingFocusedActivityLocked();
2923                }
2924            } else {
2925                startTimeTrackingFocusedActivityLocked();
2926            }
2927        } else {
2928            r.appTimeTracker = null;
2929        }
2930        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2931        // TODO: Probably not, because we don't want to resume voice on switching
2932        // back to this activity
2933        if (r.task.voiceInteractor != null) {
2934            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2935        } else {
2936            finishRunningVoiceLocked();
2937            IVoiceInteractionSession session;
2938            if (last != null && ((session = last.task.voiceSession) != null
2939                    || (session = last.voiceSession) != null)) {
2940                // We had been in a voice interaction session, but now focused has
2941                // move to something different.  Just finish the session, we can't
2942                // return to it and retain the proper state and synchronization with
2943                // the voice interaction service.
2944                finishVoiceTask(session);
2945            }
2946        }
2947        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2948            mWindowManager.setFocusedApp(r.appToken, true);
2949        }
2950        applyUpdateLockStateLocked(r);
2951        applyUpdateVrModeLocked(r);
2952        if (mFocusedActivity.userId != mLastFocusedUserId) {
2953            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2954            mHandler.obtainMessage(
2955                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2956            mLastFocusedUserId = mFocusedActivity.userId;
2957        }
2958
2959        // Log a warning if the focused app is changed during the process. This could
2960        // indicate a problem of the focus setting logic!
2961        if (mFocusedActivity != r) Slog.w(TAG,
2962                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2963        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
2964
2965        EventLogTags.writeAmFocusedActivity(
2966                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2967                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2968                reason);
2969        return true;
2970    }
2971
2972    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
2973        if (mFocusedActivity != goingAway) {
2974            return;
2975        }
2976
2977        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
2978        if (focusedStack != null) {
2979            final ActivityRecord top = focusedStack.topActivity();
2980            if (top != null && top.userId != mLastFocusedUserId) {
2981                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2982                mHandler.sendMessage(
2983                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
2984                mLastFocusedUserId = top.userId;
2985            }
2986        }
2987
2988        // Try to move focus to another activity if possible.
2989        if (setFocusedActivityLocked(
2990                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
2991            return;
2992        }
2993
2994        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
2995                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
2996        mFocusedActivity = null;
2997        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
2998    }
2999
3000    @Override
3001    public void setFocusedStack(int stackId) {
3002        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3003        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3004        final long callingId = Binder.clearCallingIdentity();
3005        try {
3006            synchronized (this) {
3007                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3008                if (stack == null) {
3009                    return;
3010                }
3011                final ActivityRecord r = stack.topRunningActivityLocked();
3012                if (setFocusedActivityLocked(r, "setFocusedStack")) {
3013                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3014                }
3015            }
3016        } finally {
3017            Binder.restoreCallingIdentity(callingId);
3018        }
3019    }
3020
3021    @Override
3022    public void setFocusedTask(int taskId) {
3023        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3024        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3025        final long callingId = Binder.clearCallingIdentity();
3026        try {
3027            synchronized (this) {
3028                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3029                if (task == null) {
3030                    return;
3031                }
3032                final ActivityRecord r = task.topRunningActivityLocked();
3033                if (setFocusedActivityLocked(r, "setFocusedTask")) {
3034                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3035                }
3036            }
3037        } finally {
3038            Binder.restoreCallingIdentity(callingId);
3039        }
3040    }
3041
3042    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3043    @Override
3044    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3045        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3046        synchronized (this) {
3047            if (listener != null) {
3048                mTaskStackListeners.register(listener);
3049            }
3050        }
3051    }
3052
3053    @Override
3054    public void notifyActivityDrawn(IBinder token) {
3055        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3056        synchronized (this) {
3057            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3058            if (r != null) {
3059                r.task.stack.notifyActivityDrawnLocked(r);
3060            }
3061        }
3062    }
3063
3064    final void applyUpdateLockStateLocked(ActivityRecord r) {
3065        // Modifications to the UpdateLock state are done on our handler, outside
3066        // the activity manager's locks.  The new state is determined based on the
3067        // state *now* of the relevant activity record.  The object is passed to
3068        // the handler solely for logging detail, not to be consulted/modified.
3069        final boolean nextState = r != null && r.immersive;
3070        mHandler.sendMessage(
3071                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3072    }
3073
3074    final void applyUpdateVrModeLocked(ActivityRecord r) {
3075        mHandler.sendMessage(
3076                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3077    }
3078
3079    private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3080        mHandler.sendMessage(
3081                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3082    }
3083
3084    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3085        Message msg = Message.obtain();
3086        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3087        msg.obj = r.task.askedCompatMode ? null : r;
3088        mUiHandler.sendMessage(msg);
3089    }
3090
3091    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3092            String what, Object obj, ProcessRecord srcApp) {
3093        app.lastActivityTime = now;
3094
3095        if (app.activities.size() > 0) {
3096            // Don't want to touch dependent processes that are hosting activities.
3097            return index;
3098        }
3099
3100        int lrui = mLruProcesses.lastIndexOf(app);
3101        if (lrui < 0) {
3102            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3103                    + what + " " + obj + " from " + srcApp);
3104            return index;
3105        }
3106
3107        if (lrui >= index) {
3108            // Don't want to cause this to move dependent processes *back* in the
3109            // list as if they were less frequently used.
3110            return index;
3111        }
3112
3113        if (lrui >= mLruProcessActivityStart) {
3114            // Don't want to touch dependent processes that are hosting activities.
3115            return index;
3116        }
3117
3118        mLruProcesses.remove(lrui);
3119        if (index > 0) {
3120            index--;
3121        }
3122        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3123                + " in LRU list: " + app);
3124        mLruProcesses.add(index, app);
3125        return index;
3126    }
3127
3128    static void killProcessGroup(int uid, int pid) {
3129        if (sKillHandler != null) {
3130            sKillHandler.sendMessage(
3131                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3132        } else {
3133            Slog.w(TAG, "Asked to kill process group before system bringup!");
3134            Process.killProcessGroup(uid, pid);
3135        }
3136    }
3137
3138    final void removeLruProcessLocked(ProcessRecord app) {
3139        int lrui = mLruProcesses.lastIndexOf(app);
3140        if (lrui >= 0) {
3141            if (!app.killed) {
3142                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3143                Process.killProcessQuiet(app.pid);
3144                killProcessGroup(app.uid, app.pid);
3145            }
3146            if (lrui <= mLruProcessActivityStart) {
3147                mLruProcessActivityStart--;
3148            }
3149            if (lrui <= mLruProcessServiceStart) {
3150                mLruProcessServiceStart--;
3151            }
3152            mLruProcesses.remove(lrui);
3153        }
3154    }
3155
3156    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3157            ProcessRecord client) {
3158        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3159                || app.treatLikeActivity;
3160        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3161        if (!activityChange && hasActivity) {
3162            // The process has activities, so we are only allowing activity-based adjustments
3163            // to move it.  It should be kept in the front of the list with other
3164            // processes that have activities, and we don't want those to change their
3165            // order except due to activity operations.
3166            return;
3167        }
3168
3169        mLruSeq++;
3170        final long now = SystemClock.uptimeMillis();
3171        app.lastActivityTime = now;
3172
3173        // First a quick reject: if the app is already at the position we will
3174        // put it, then there is nothing to do.
3175        if (hasActivity) {
3176            final int N = mLruProcesses.size();
3177            if (N > 0 && mLruProcesses.get(N-1) == app) {
3178                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3179                return;
3180            }
3181        } else {
3182            if (mLruProcessServiceStart > 0
3183                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3184                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3185                return;
3186            }
3187        }
3188
3189        int lrui = mLruProcesses.lastIndexOf(app);
3190
3191        if (app.persistent && lrui >= 0) {
3192            // We don't care about the position of persistent processes, as long as
3193            // they are in the list.
3194            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3195            return;
3196        }
3197
3198        /* In progress: compute new position first, so we can avoid doing work
3199           if the process is not actually going to move.  Not yet working.
3200        int addIndex;
3201        int nextIndex;
3202        boolean inActivity = false, inService = false;
3203        if (hasActivity) {
3204            // Process has activities, put it at the very tipsy-top.
3205            addIndex = mLruProcesses.size();
3206            nextIndex = mLruProcessServiceStart;
3207            inActivity = true;
3208        } else if (hasService) {
3209            // Process has services, put it at the top of the service list.
3210            addIndex = mLruProcessActivityStart;
3211            nextIndex = mLruProcessServiceStart;
3212            inActivity = true;
3213            inService = true;
3214        } else  {
3215            // Process not otherwise of interest, it goes to the top of the non-service area.
3216            addIndex = mLruProcessServiceStart;
3217            if (client != null) {
3218                int clientIndex = mLruProcesses.lastIndexOf(client);
3219                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3220                        + app);
3221                if (clientIndex >= 0 && addIndex > clientIndex) {
3222                    addIndex = clientIndex;
3223                }
3224            }
3225            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3226        }
3227
3228        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3229                + mLruProcessActivityStart + "): " + app);
3230        */
3231
3232        if (lrui >= 0) {
3233            if (lrui < mLruProcessActivityStart) {
3234                mLruProcessActivityStart--;
3235            }
3236            if (lrui < mLruProcessServiceStart) {
3237                mLruProcessServiceStart--;
3238            }
3239            /*
3240            if (addIndex > lrui) {
3241                addIndex--;
3242            }
3243            if (nextIndex > lrui) {
3244                nextIndex--;
3245            }
3246            */
3247            mLruProcesses.remove(lrui);
3248        }
3249
3250        /*
3251        mLruProcesses.add(addIndex, app);
3252        if (inActivity) {
3253            mLruProcessActivityStart++;
3254        }
3255        if (inService) {
3256            mLruProcessActivityStart++;
3257        }
3258        */
3259
3260        int nextIndex;
3261        if (hasActivity) {
3262            final int N = mLruProcesses.size();
3263            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3264                // Process doesn't have activities, but has clients with
3265                // activities...  move it up, but one below the top (the top
3266                // should always have a real activity).
3267                if (DEBUG_LRU) Slog.d(TAG_LRU,
3268                        "Adding to second-top of LRU activity list: " + app);
3269                mLruProcesses.add(N - 1, app);
3270                // To keep it from spamming the LRU list (by making a bunch of clients),
3271                // we will push down any other entries owned by the app.
3272                final int uid = app.info.uid;
3273                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3274                    ProcessRecord subProc = mLruProcesses.get(i);
3275                    if (subProc.info.uid == uid) {
3276                        // We want to push this one down the list.  If the process after
3277                        // it is for the same uid, however, don't do so, because we don't
3278                        // want them internally to be re-ordered.
3279                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3280                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3281                                    "Pushing uid " + uid + " swapping at " + i + ": "
3282                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3283                            ProcessRecord tmp = mLruProcesses.get(i);
3284                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3285                            mLruProcesses.set(i - 1, tmp);
3286                            i--;
3287                        }
3288                    } else {
3289                        // A gap, we can stop here.
3290                        break;
3291                    }
3292                }
3293            } else {
3294                // Process has activities, put it at the very tipsy-top.
3295                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3296                mLruProcesses.add(app);
3297            }
3298            nextIndex = mLruProcessServiceStart;
3299        } else if (hasService) {
3300            // Process has services, put it at the top of the service list.
3301            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3302            mLruProcesses.add(mLruProcessActivityStart, app);
3303            nextIndex = mLruProcessServiceStart;
3304            mLruProcessActivityStart++;
3305        } else  {
3306            // Process not otherwise of interest, it goes to the top of the non-service area.
3307            int index = mLruProcessServiceStart;
3308            if (client != null) {
3309                // If there is a client, don't allow the process to be moved up higher
3310                // in the list than that client.
3311                int clientIndex = mLruProcesses.lastIndexOf(client);
3312                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3313                        + " when updating " + app);
3314                if (clientIndex <= lrui) {
3315                    // Don't allow the client index restriction to push it down farther in the
3316                    // list than it already is.
3317                    clientIndex = lrui;
3318                }
3319                if (clientIndex >= 0 && index > clientIndex) {
3320                    index = clientIndex;
3321                }
3322            }
3323            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3324            mLruProcesses.add(index, app);
3325            nextIndex = index-1;
3326            mLruProcessActivityStart++;
3327            mLruProcessServiceStart++;
3328        }
3329
3330        // If the app is currently using a content provider or service,
3331        // bump those processes as well.
3332        for (int j=app.connections.size()-1; j>=0; j--) {
3333            ConnectionRecord cr = app.connections.valueAt(j);
3334            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3335                    && cr.binding.service.app != null
3336                    && cr.binding.service.app.lruSeq != mLruSeq
3337                    && !cr.binding.service.app.persistent) {
3338                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3339                        "service connection", cr, app);
3340            }
3341        }
3342        for (int j=app.conProviders.size()-1; j>=0; j--) {
3343            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3344            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3345                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3346                        "provider reference", cpr, app);
3347            }
3348        }
3349    }
3350
3351    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3352        if (uid == Process.SYSTEM_UID) {
3353            // The system gets to run in any process.  If there are multiple
3354            // processes with the same uid, just pick the first (this
3355            // should never happen).
3356            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3357            if (procs == null) return null;
3358            final int procCount = procs.size();
3359            for (int i = 0; i < procCount; i++) {
3360                final int procUid = procs.keyAt(i);
3361                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3362                    // Don't use an app process or different user process for system component.
3363                    continue;
3364                }
3365                return procs.valueAt(i);
3366            }
3367        }
3368        ProcessRecord proc = mProcessNames.get(processName, uid);
3369        if (false && proc != null && !keepIfLarge
3370                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3371                && proc.lastCachedPss >= 4000) {
3372            // Turn this condition on to cause killing to happen regularly, for testing.
3373            if (proc.baseProcessTracker != null) {
3374                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3375            }
3376            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3377        } else if (proc != null && !keepIfLarge
3378                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3379                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3380            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3381            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3382                if (proc.baseProcessTracker != null) {
3383                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3384                }
3385                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3386            }
3387        }
3388        return proc;
3389    }
3390
3391    void notifyPackageUse(String packageName, int reason) {
3392        IPackageManager pm = AppGlobals.getPackageManager();
3393        try {
3394            pm.notifyPackageUse(packageName, reason);
3395        } catch (RemoteException e) {
3396        }
3397    }
3398
3399    boolean isNextTransitionForward() {
3400        int transit = mWindowManager.getPendingAppTransition();
3401        return transit == TRANSIT_ACTIVITY_OPEN
3402                || transit == TRANSIT_TASK_OPEN
3403                || transit == TRANSIT_TASK_TO_FRONT;
3404    }
3405
3406    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3407            String processName, String abiOverride, int uid, Runnable crashHandler) {
3408        synchronized(this) {
3409            ApplicationInfo info = new ApplicationInfo();
3410            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3411            // For isolated processes, the former contains the parent's uid and the latter the
3412            // actual uid of the isolated process.
3413            // In the special case introduced by this method (which is, starting an isolated
3414            // process directly from the SystemServer without an actual parent app process) the
3415            // closest thing to a parent's uid is SYSTEM_UID.
3416            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3417            // the |isolated| logic in the ProcessRecord constructor.
3418            info.uid = Process.SYSTEM_UID;
3419            info.processName = processName;
3420            info.className = entryPoint;
3421            info.packageName = "android";
3422            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3423                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3424                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3425                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3426                    crashHandler);
3427            return proc != null ? proc.pid : 0;
3428        }
3429    }
3430
3431    final ProcessRecord startProcessLocked(String processName,
3432            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3433            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3434            boolean isolated, boolean keepIfLarge) {
3435        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3436                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3437                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3438                null /* crashHandler */);
3439    }
3440
3441    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3442            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3443            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3444            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3445        long startTime = SystemClock.elapsedRealtime();
3446        ProcessRecord app;
3447        if (!isolated) {
3448            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3449            checkTime(startTime, "startProcess: after getProcessRecord");
3450
3451            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3452                // If we are in the background, then check to see if this process
3453                // is bad.  If so, we will just silently fail.
3454                if (mAppErrors.isBadProcessLocked(info)) {
3455                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3456                            + "/" + info.processName);
3457                    return null;
3458                }
3459            } else {
3460                // When the user is explicitly starting a process, then clear its
3461                // crash count so that we won't make it bad until they see at
3462                // least one crash dialog again, and make the process good again
3463                // if it had been bad.
3464                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3465                        + "/" + info.processName);
3466                mAppErrors.resetProcessCrashTimeLocked(info);
3467                if (mAppErrors.isBadProcessLocked(info)) {
3468                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3469                            UserHandle.getUserId(info.uid), info.uid,
3470                            info.processName);
3471                    mAppErrors.clearBadProcessLocked(info);
3472                    if (app != null) {
3473                        app.bad = false;
3474                    }
3475                }
3476            }
3477        } else {
3478            // If this is an isolated process, it can't re-use an existing process.
3479            app = null;
3480        }
3481
3482        // app launch boost for big.little configurations
3483        // use cpusets to migrate freshly launched tasks to big cores
3484        synchronized(ActivityManagerService.this) {
3485            nativeMigrateToBoost();
3486            mIsBoosted = true;
3487            mBoostStartTime = SystemClock.uptimeMillis();
3488            Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3489            mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3490        }
3491
3492        // We don't have to do anything more if:
3493        // (1) There is an existing application record; and
3494        // (2) The caller doesn't think it is dead, OR there is no thread
3495        //     object attached to it so we know it couldn't have crashed; and
3496        // (3) There is a pid assigned to it, so it is either starting or
3497        //     already running.
3498        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3499                + " app=" + app + " knownToBeDead=" + knownToBeDead
3500                + " thread=" + (app != null ? app.thread : null)
3501                + " pid=" + (app != null ? app.pid : -1));
3502        if (app != null && app.pid > 0) {
3503            if (!knownToBeDead || app.thread == null) {
3504                // We already have the app running, or are waiting for it to
3505                // come up (we have a pid but not yet its thread), so keep it.
3506                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3507                // If this is a new package in the process, add the package to the list
3508                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3509                checkTime(startTime, "startProcess: done, added package to proc");
3510                return app;
3511            }
3512
3513            // An application record is attached to a previous process,
3514            // clean it up now.
3515            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3516            checkTime(startTime, "startProcess: bad proc running, killing");
3517            killProcessGroup(app.uid, app.pid);
3518            handleAppDiedLocked(app, true, true);
3519            checkTime(startTime, "startProcess: done killing old proc");
3520        }
3521
3522        String hostingNameStr = hostingName != null
3523                ? hostingName.flattenToShortString() : null;
3524
3525        if (app == null) {
3526            checkTime(startTime, "startProcess: creating new process record");
3527            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3528            if (app == null) {
3529                Slog.w(TAG, "Failed making new process record for "
3530                        + processName + "/" + info.uid + " isolated=" + isolated);
3531                return null;
3532            }
3533            app.crashHandler = crashHandler;
3534            checkTime(startTime, "startProcess: done creating new process record");
3535        } else {
3536            // If this is a new package in the process, add the package to the list
3537            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3538            checkTime(startTime, "startProcess: added package to existing proc");
3539        }
3540
3541        // If the system is not ready yet, then hold off on starting this
3542        // process until it is.
3543        if (!mProcessesReady
3544                && !isAllowedWhileBooting(info)
3545                && !allowWhileBooting) {
3546            if (!mProcessesOnHold.contains(app)) {
3547                mProcessesOnHold.add(app);
3548            }
3549            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3550                    "System not ready, putting on hold: " + app);
3551            checkTime(startTime, "startProcess: returning with proc on hold");
3552            return app;
3553        }
3554
3555        checkTime(startTime, "startProcess: stepping in to startProcess");
3556        startProcessLocked(
3557                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3558        checkTime(startTime, "startProcess: done starting proc!");
3559        return (app.pid != 0) ? app : null;
3560    }
3561
3562    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3563        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3564    }
3565
3566    private final void startProcessLocked(ProcessRecord app,
3567            String hostingType, String hostingNameStr) {
3568        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3569                null /* entryPoint */, null /* entryPointArgs */);
3570    }
3571
3572    private final void startProcessLocked(ProcessRecord app, String hostingType,
3573            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3574        long startTime = SystemClock.elapsedRealtime();
3575        if (app.pid > 0 && app.pid != MY_PID) {
3576            checkTime(startTime, "startProcess: removing from pids map");
3577            synchronized (mPidsSelfLocked) {
3578                mPidsSelfLocked.remove(app.pid);
3579                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3580            }
3581            checkTime(startTime, "startProcess: done removing from pids map");
3582            app.setPid(0);
3583        }
3584
3585        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3586                "startProcessLocked removing on hold: " + app);
3587        mProcessesOnHold.remove(app);
3588
3589        checkTime(startTime, "startProcess: starting to update cpu stats");
3590        updateCpuStats();
3591        checkTime(startTime, "startProcess: done updating cpu stats");
3592
3593        try {
3594            try {
3595                final int userId = UserHandle.getUserId(app.uid);
3596                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3597            } catch (RemoteException e) {
3598                throw e.rethrowAsRuntimeException();
3599            }
3600
3601            int uid = app.uid;
3602            int[] gids = null;
3603            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3604            if (!app.isolated) {
3605                int[] permGids = null;
3606                try {
3607                    checkTime(startTime, "startProcess: getting gids from package manager");
3608                    final IPackageManager pm = AppGlobals.getPackageManager();
3609                    permGids = pm.getPackageGids(app.info.packageName,
3610                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3611                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3612                            MountServiceInternal.class);
3613                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3614                            app.info.packageName);
3615                } catch (RemoteException e) {
3616                    throw e.rethrowAsRuntimeException();
3617                }
3618
3619                /*
3620                 * Add shared application and profile GIDs so applications can share some
3621                 * resources like shared libraries and access user-wide resources
3622                 */
3623                if (ArrayUtils.isEmpty(permGids)) {
3624                    gids = new int[2];
3625                } else {
3626                    gids = new int[permGids.length + 2];
3627                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3628                }
3629                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3630                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3631            }
3632            checkTime(startTime, "startProcess: building args");
3633            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3634                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3635                        && mTopComponent != null
3636                        && app.processName.equals(mTopComponent.getPackageName())) {
3637                    uid = 0;
3638                }
3639                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3640                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3641                    uid = 0;
3642                }
3643            }
3644            int debugFlags = 0;
3645            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3646                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3647                // Also turn on CheckJNI for debuggable apps. It's quite
3648                // awkward to turn on otherwise.
3649                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3650            }
3651            // Run the app in safe mode if its manifest requests so or the
3652            // system is booted in safe mode.
3653            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3654                mSafeMode == true) {
3655                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3656            }
3657            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3658                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3659            }
3660            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3661            if ("true".equals(genDebugInfoProperty)) {
3662                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3663            }
3664            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3665                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3666            }
3667            if ("1".equals(SystemProperties.get("debug.assert"))) {
3668                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3669            }
3670            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3671                // Enable all debug flags required by the native debugger.
3672                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3673                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3674                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3675                mNativeDebuggingApp = null;
3676            }
3677
3678            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3679            if (requiredAbi == null) {
3680                requiredAbi = Build.SUPPORTED_ABIS[0];
3681            }
3682
3683            String instructionSet = null;
3684            if (app.info.primaryCpuAbi != null) {
3685                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3686            }
3687
3688            app.gids = gids;
3689            app.requiredAbi = requiredAbi;
3690            app.instructionSet = instructionSet;
3691
3692            // Start the process.  It will either succeed and return a result containing
3693            // the PID of the new process, or else throw a RuntimeException.
3694            boolean isActivityProcess = (entryPoint == null);
3695            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3696            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3697                    app.processName);
3698            checkTime(startTime, "startProcess: asking zygote to start proc");
3699            Process.ProcessStartResult startResult = Process.start(entryPoint,
3700                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3701                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3702                    app.info.dataDir, entryPointArgs);
3703            checkTime(startTime, "startProcess: returned from zygote!");
3704            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3705
3706            if (app.isolated) {
3707                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3708            }
3709            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3710            checkTime(startTime, "startProcess: done updating battery stats");
3711
3712            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3713                    UserHandle.getUserId(uid), startResult.pid, uid,
3714                    app.processName, hostingType,
3715                    hostingNameStr != null ? hostingNameStr : "");
3716
3717            try {
3718                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3719                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3720            } catch (RemoteException ex) {
3721                // Ignore
3722            }
3723
3724            if (app.persistent) {
3725                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3726            }
3727
3728            checkTime(startTime, "startProcess: building log message");
3729            StringBuilder buf = mStringBuilder;
3730            buf.setLength(0);
3731            buf.append("Start proc ");
3732            buf.append(startResult.pid);
3733            buf.append(':');
3734            buf.append(app.processName);
3735            buf.append('/');
3736            UserHandle.formatUid(buf, uid);
3737            if (!isActivityProcess) {
3738                buf.append(" [");
3739                buf.append(entryPoint);
3740                buf.append("]");
3741            }
3742            buf.append(" for ");
3743            buf.append(hostingType);
3744            if (hostingNameStr != null) {
3745                buf.append(" ");
3746                buf.append(hostingNameStr);
3747            }
3748            Slog.i(TAG, buf.toString());
3749            app.setPid(startResult.pid);
3750            app.usingWrapper = startResult.usingWrapper;
3751            app.removed = false;
3752            app.killed = false;
3753            app.killedByAm = false;
3754            checkTime(startTime, "startProcess: starting to update pids map");
3755            synchronized (mPidsSelfLocked) {
3756                this.mPidsSelfLocked.put(startResult.pid, app);
3757                if (isActivityProcess) {
3758                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3759                    msg.obj = app;
3760                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3761                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3762                }
3763            }
3764            checkTime(startTime, "startProcess: done updating pids map");
3765        } catch (RuntimeException e) {
3766            Slog.e(TAG, "Failure starting process " + app.processName, e);
3767
3768            // Something went very wrong while trying to start this process; one
3769            // common case is when the package is frozen due to an active
3770            // upgrade. To recover, clean up any active bookkeeping related to
3771            // starting this process. (We already invoked this method once when
3772            // the package was initially frozen through KILL_APPLICATION_MSG, so
3773            // it doesn't hurt to use it again.)
3774            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3775                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3776        }
3777    }
3778
3779    void updateUsageStats(ActivityRecord component, boolean resumed) {
3780        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3781                "updateUsageStats: comp=" + component + "res=" + resumed);
3782        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3783        if (resumed) {
3784            if (mUsageStatsService != null) {
3785                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3786                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3787            }
3788            synchronized (stats) {
3789                stats.noteActivityResumedLocked(component.app.uid);
3790            }
3791        } else {
3792            if (mUsageStatsService != null) {
3793                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3794                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3795            }
3796            synchronized (stats) {
3797                stats.noteActivityPausedLocked(component.app.uid);
3798            }
3799        }
3800    }
3801
3802    Intent getHomeIntent() {
3803        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3804        intent.setComponent(mTopComponent);
3805        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3806        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3807            intent.addCategory(Intent.CATEGORY_HOME);
3808        }
3809        return intent;
3810    }
3811
3812    boolean startHomeActivityLocked(int userId, String reason) {
3813        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3814                && mTopAction == null) {
3815            // We are running in factory test mode, but unable to find
3816            // the factory test app, so just sit around displaying the
3817            // error message and don't try to start anything.
3818            return false;
3819        }
3820        Intent intent = getHomeIntent();
3821        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3822        if (aInfo != null) {
3823            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3824            // Don't do this if the home app is currently being
3825            // instrumented.
3826            aInfo = new ActivityInfo(aInfo);
3827            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3828            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3829                    aInfo.applicationInfo.uid, true);
3830            if (app == null || app.instrumentationClass == null) {
3831                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3832                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3833            }
3834        } else {
3835            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3836        }
3837
3838        return true;
3839    }
3840
3841    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3842        ActivityInfo ai = null;
3843        ComponentName comp = intent.getComponent();
3844        try {
3845            if (comp != null) {
3846                // Factory test.
3847                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3848            } else {
3849                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3850                        intent,
3851                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3852                        flags, userId);
3853
3854                if (info != null) {
3855                    ai = info.activityInfo;
3856                }
3857            }
3858        } catch (RemoteException e) {
3859            // ignore
3860        }
3861
3862        return ai;
3863    }
3864
3865    /**
3866     * Starts the "new version setup screen" if appropriate.
3867     */
3868    void startSetupActivityLocked() {
3869        // Only do this once per boot.
3870        if (mCheckedForSetup) {
3871            return;
3872        }
3873
3874        // We will show this screen if the current one is a different
3875        // version than the last one shown, and we are not running in
3876        // low-level factory test mode.
3877        final ContentResolver resolver = mContext.getContentResolver();
3878        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3879                Settings.Global.getInt(resolver,
3880                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3881            mCheckedForSetup = true;
3882
3883            // See if we should be showing the platform update setup UI.
3884            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3885            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3886                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3887            if (!ris.isEmpty()) {
3888                final ResolveInfo ri = ris.get(0);
3889                String vers = ri.activityInfo.metaData != null
3890                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3891                        : null;
3892                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3893                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3894                            Intent.METADATA_SETUP_VERSION);
3895                }
3896                String lastVers = Settings.Secure.getString(
3897                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3898                if (vers != null && !vers.equals(lastVers)) {
3899                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3900                    intent.setComponent(new ComponentName(
3901                            ri.activityInfo.packageName, ri.activityInfo.name));
3902                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3903                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3904                            null, 0, 0, 0, null, false, false, null, null, null);
3905                }
3906            }
3907        }
3908    }
3909
3910    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3911        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3912    }
3913
3914    void enforceNotIsolatedCaller(String caller) {
3915        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3916            throw new SecurityException("Isolated process not allowed to call " + caller);
3917        }
3918    }
3919
3920    void enforceShellRestriction(String restriction, int userHandle) {
3921        if (Binder.getCallingUid() == Process.SHELL_UID) {
3922            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3923                throw new SecurityException("Shell does not have permission to access user "
3924                        + userHandle);
3925            }
3926        }
3927    }
3928
3929    @Override
3930    public int getFrontActivityScreenCompatMode() {
3931        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3932        synchronized (this) {
3933            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3934        }
3935    }
3936
3937    @Override
3938    public void setFrontActivityScreenCompatMode(int mode) {
3939        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3940                "setFrontActivityScreenCompatMode");
3941        synchronized (this) {
3942            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3943        }
3944    }
3945
3946    @Override
3947    public int getPackageScreenCompatMode(String packageName) {
3948        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3949        synchronized (this) {
3950            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3951        }
3952    }
3953
3954    @Override
3955    public void setPackageScreenCompatMode(String packageName, int mode) {
3956        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3957                "setPackageScreenCompatMode");
3958        synchronized (this) {
3959            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3960        }
3961    }
3962
3963    @Override
3964    public boolean getPackageAskScreenCompat(String packageName) {
3965        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3966        synchronized (this) {
3967            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3968        }
3969    }
3970
3971    @Override
3972    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3973        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3974                "setPackageAskScreenCompat");
3975        synchronized (this) {
3976            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3977        }
3978    }
3979
3980    private boolean hasUsageStatsPermission(String callingPackage) {
3981        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3982                Binder.getCallingUid(), callingPackage);
3983        if (mode == AppOpsManager.MODE_DEFAULT) {
3984            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3985                    == PackageManager.PERMISSION_GRANTED;
3986        }
3987        return mode == AppOpsManager.MODE_ALLOWED;
3988    }
3989
3990    @Override
3991    public int getPackageProcessState(String packageName, String callingPackage) {
3992        if (!hasUsageStatsPermission(callingPackage)) {
3993            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3994                    "getPackageProcessState");
3995        }
3996
3997        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3998        synchronized (this) {
3999            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4000                final ProcessRecord proc = mLruProcesses.get(i);
4001                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4002                        || procState > proc.setProcState) {
4003                    boolean found = false;
4004                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4005                        if (proc.pkgList.keyAt(j).equals(packageName)) {
4006                            procState = proc.setProcState;
4007                            found = true;
4008                        }
4009                    }
4010                    if (proc.pkgDeps != null && !found) {
4011                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4012                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4013                                procState = proc.setProcState;
4014                                break;
4015                            }
4016                        }
4017                    }
4018                }
4019            }
4020        }
4021        return procState;
4022    }
4023
4024    @Override
4025    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
4026        synchronized (this) {
4027            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4028            if (app == null) {
4029                return false;
4030            }
4031            if (app.trimMemoryLevel < level && app.thread != null &&
4032                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4033                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4034                try {
4035                    app.thread.scheduleTrimMemory(level);
4036                    app.trimMemoryLevel = level;
4037                    return true;
4038                } catch (RemoteException e) {
4039                    // Fallthrough to failure case.
4040                }
4041            }
4042        }
4043        return false;
4044    }
4045
4046    private void dispatchProcessesChanged() {
4047        int N;
4048        synchronized (this) {
4049            N = mPendingProcessChanges.size();
4050            if (mActiveProcessChanges.length < N) {
4051                mActiveProcessChanges = new ProcessChangeItem[N];
4052            }
4053            mPendingProcessChanges.toArray(mActiveProcessChanges);
4054            mPendingProcessChanges.clear();
4055            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4056                    "*** Delivering " + N + " process changes");
4057        }
4058
4059        int i = mProcessObservers.beginBroadcast();
4060        while (i > 0) {
4061            i--;
4062            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4063            if (observer != null) {
4064                try {
4065                    for (int j=0; j<N; j++) {
4066                        ProcessChangeItem item = mActiveProcessChanges[j];
4067                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4068                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4069                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4070                                    + item.uid + ": " + item.foregroundActivities);
4071                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4072                                    item.foregroundActivities);
4073                        }
4074                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4075                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4076                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4077                                    + ": " + item.processState);
4078                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4079                        }
4080                    }
4081                } catch (RemoteException e) {
4082                }
4083            }
4084        }
4085        mProcessObservers.finishBroadcast();
4086
4087        synchronized (this) {
4088            for (int j=0; j<N; j++) {
4089                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4090            }
4091        }
4092    }
4093
4094    private void dispatchProcessDied(int pid, int uid) {
4095        int i = mProcessObservers.beginBroadcast();
4096        while (i > 0) {
4097            i--;
4098            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4099            if (observer != null) {
4100                try {
4101                    observer.onProcessDied(pid, uid);
4102                } catch (RemoteException e) {
4103                }
4104            }
4105        }
4106        mProcessObservers.finishBroadcast();
4107    }
4108
4109    private void dispatchUidsChanged() {
4110        int N;
4111        synchronized (this) {
4112            N = mPendingUidChanges.size();
4113            if (mActiveUidChanges.length < N) {
4114                mActiveUidChanges = new UidRecord.ChangeItem[N];
4115            }
4116            for (int i=0; i<N; i++) {
4117                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4118                mActiveUidChanges[i] = change;
4119                if (change.uidRecord != null) {
4120                    change.uidRecord.pendingChange = null;
4121                    change.uidRecord = null;
4122                }
4123            }
4124            mPendingUidChanges.clear();
4125            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4126                    "*** Delivering " + N + " uid changes");
4127        }
4128
4129        if (mLocalPowerManager != null) {
4130            for (int j=0; j<N; j++) {
4131                UidRecord.ChangeItem item = mActiveUidChanges[j];
4132                if (item.change == UidRecord.CHANGE_GONE
4133                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4134                    mLocalPowerManager.uidGone(item.uid);
4135                } else {
4136                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4137                }
4138            }
4139        }
4140
4141        int i = mUidObservers.beginBroadcast();
4142        while (i > 0) {
4143            i--;
4144            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4145            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4146            if (observer != null) {
4147                try {
4148                    for (int j=0; j<N; j++) {
4149                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4150                        final int change = item.change;
4151                        UidRecord validateUid = null;
4152                        if (VALIDATE_UID_STATES && i == 0) {
4153                            validateUid = mValidateUids.get(item.uid);
4154                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4155                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4156                                validateUid = new UidRecord(item.uid);
4157                                mValidateUids.put(item.uid, validateUid);
4158                            }
4159                        }
4160                        if (change == UidRecord.CHANGE_IDLE
4161                                || change == UidRecord.CHANGE_GONE_IDLE) {
4162                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4163                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4164                                        "UID idle uid=" + item.uid);
4165                                observer.onUidIdle(item.uid);
4166                            }
4167                            if (VALIDATE_UID_STATES && i == 0) {
4168                                if (validateUid != null) {
4169                                    validateUid.idle = true;
4170                                }
4171                            }
4172                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4173                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4174                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4175                                        "UID active uid=" + item.uid);
4176                                observer.onUidActive(item.uid);
4177                            }
4178                            if (VALIDATE_UID_STATES && i == 0) {
4179                                validateUid.idle = false;
4180                            }
4181                        }
4182                        if (change == UidRecord.CHANGE_GONE
4183                                || change == UidRecord.CHANGE_GONE_IDLE) {
4184                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4185                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4186                                        "UID gone uid=" + item.uid);
4187                                observer.onUidGone(item.uid);
4188                            }
4189                            if (VALIDATE_UID_STATES && i == 0) {
4190                                if (validateUid != null) {
4191                                    mValidateUids.remove(item.uid);
4192                                }
4193                            }
4194                        } else {
4195                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4196                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4197                                        "UID CHANGED uid=" + item.uid
4198                                                + ": " + item.processState);
4199                                observer.onUidStateChanged(item.uid, item.processState);
4200                            }
4201                            if (VALIDATE_UID_STATES && i == 0) {
4202                                validateUid.curProcState = validateUid.setProcState
4203                                        = item.processState;
4204                            }
4205                        }
4206                    }
4207                } catch (RemoteException e) {
4208                }
4209            }
4210        }
4211        mUidObservers.finishBroadcast();
4212
4213        synchronized (this) {
4214            for (int j=0; j<N; j++) {
4215                mAvailUidChanges.add(mActiveUidChanges[j]);
4216            }
4217        }
4218    }
4219
4220    @Override
4221    public final int startActivity(IApplicationThread caller, String callingPackage,
4222            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4223            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4224        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4225                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4226                UserHandle.getCallingUserId());
4227    }
4228
4229    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4230        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4231        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4232                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4233                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4234
4235        // TODO: Switch to user app stacks here.
4236        String mimeType = intent.getType();
4237        final Uri data = intent.getData();
4238        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4239            mimeType = getProviderMimeType(data, userId);
4240        }
4241        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4242
4243        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4244        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4245                null, 0, 0, null, null, null, null, false, userId, container, null);
4246    }
4247
4248    @Override
4249    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4250            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4251            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4252        enforceNotIsolatedCaller("startActivity");
4253        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4254                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4255        // TODO: Switch to user app stacks here.
4256        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4257                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4258                profilerInfo, null, null, bOptions, false, userId, null, null);
4259    }
4260
4261    @Override
4262    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4263            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4264            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4265            int userId) {
4266
4267        // This is very dangerous -- it allows you to perform a start activity (including
4268        // permission grants) as any app that may launch one of your own activities.  So
4269        // we will only allow this to be done from activities that are part of the core framework,
4270        // and then only when they are running as the system.
4271        final ActivityRecord sourceRecord;
4272        final int targetUid;
4273        final String targetPackage;
4274        synchronized (this) {
4275            if (resultTo == null) {
4276                throw new SecurityException("Must be called from an activity");
4277            }
4278            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4279            if (sourceRecord == null) {
4280                throw new SecurityException("Called with bad activity token: " + resultTo);
4281            }
4282            if (!sourceRecord.info.packageName.equals("android")) {
4283                throw new SecurityException(
4284                        "Must be called from an activity that is declared in the android package");
4285            }
4286            if (sourceRecord.app == null) {
4287                throw new SecurityException("Called without a process attached to activity");
4288            }
4289            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4290                // This is still okay, as long as this activity is running under the
4291                // uid of the original calling activity.
4292                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4293                    throw new SecurityException(
4294                            "Calling activity in uid " + sourceRecord.app.uid
4295                                    + " must be system uid or original calling uid "
4296                                    + sourceRecord.launchedFromUid);
4297                }
4298            }
4299            if (ignoreTargetSecurity) {
4300                if (intent.getComponent() == null) {
4301                    throw new SecurityException(
4302                            "Component must be specified with ignoreTargetSecurity");
4303                }
4304                if (intent.getSelector() != null) {
4305                    throw new SecurityException(
4306                            "Selector not allowed with ignoreTargetSecurity");
4307                }
4308            }
4309            targetUid = sourceRecord.launchedFromUid;
4310            targetPackage = sourceRecord.launchedFromPackage;
4311        }
4312
4313        if (userId == UserHandle.USER_NULL) {
4314            userId = UserHandle.getUserId(sourceRecord.app.uid);
4315        }
4316
4317        // TODO: Switch to user app stacks here.
4318        try {
4319            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4320                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4321                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4322            return ret;
4323        } catch (SecurityException e) {
4324            // XXX need to figure out how to propagate to original app.
4325            // A SecurityException here is generally actually a fault of the original
4326            // calling activity (such as a fairly granting permissions), so propagate it
4327            // back to them.
4328            /*
4329            StringBuilder msg = new StringBuilder();
4330            msg.append("While launching");
4331            msg.append(intent.toString());
4332            msg.append(": ");
4333            msg.append(e.getMessage());
4334            */
4335            throw e;
4336        }
4337    }
4338
4339    @Override
4340    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4341            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4342            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4343        enforceNotIsolatedCaller("startActivityAndWait");
4344        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4345                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4346        WaitResult res = new WaitResult();
4347        // TODO: Switch to user app stacks here.
4348        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4349                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4350                bOptions, false, userId, null, null);
4351        return res;
4352    }
4353
4354    @Override
4355    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4356            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4357            int startFlags, Configuration config, Bundle bOptions, int userId) {
4358        enforceNotIsolatedCaller("startActivityWithConfig");
4359        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4360                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4361        // TODO: Switch to user app stacks here.
4362        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4363                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4364                null, null, config, bOptions, false, userId, null, null);
4365        return ret;
4366    }
4367
4368    @Override
4369    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4370            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4371            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4372            throws TransactionTooLargeException {
4373        enforceNotIsolatedCaller("startActivityIntentSender");
4374        // Refuse possible leaked file descriptors
4375        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4376            throw new IllegalArgumentException("File descriptors passed in Intent");
4377        }
4378
4379        IIntentSender sender = intent.getTarget();
4380        if (!(sender instanceof PendingIntentRecord)) {
4381            throw new IllegalArgumentException("Bad PendingIntent object");
4382        }
4383
4384        PendingIntentRecord pir = (PendingIntentRecord)sender;
4385
4386        synchronized (this) {
4387            // If this is coming from the currently resumed activity, it is
4388            // effectively saying that app switches are allowed at this point.
4389            final ActivityStack stack = getFocusedStack();
4390            if (stack.mResumedActivity != null &&
4391                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4392                mAppSwitchesAllowedTime = 0;
4393            }
4394        }
4395        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4396                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4397        return ret;
4398    }
4399
4400    @Override
4401    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4402            Intent intent, String resolvedType, IVoiceInteractionSession session,
4403            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4404            Bundle bOptions, int userId) {
4405        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4406                != PackageManager.PERMISSION_GRANTED) {
4407            String msg = "Permission Denial: startVoiceActivity() from pid="
4408                    + Binder.getCallingPid()
4409                    + ", uid=" + Binder.getCallingUid()
4410                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4411            Slog.w(TAG, msg);
4412            throw new SecurityException(msg);
4413        }
4414        if (session == null || interactor == null) {
4415            throw new NullPointerException("null session or interactor");
4416        }
4417        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4418                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4419        // TODO: Switch to user app stacks here.
4420        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4421                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4422                null, bOptions, false, userId, null, null);
4423    }
4424
4425    @Override
4426    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4427            throws RemoteException {
4428        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4429        synchronized (this) {
4430            ActivityRecord activity = getFocusedStack().topActivity();
4431            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4432                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4433            }
4434            if (mRunningVoice != null || activity.task.voiceSession != null
4435                    || activity.voiceSession != null) {
4436                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4437                return;
4438            }
4439            if (activity.pendingVoiceInteractionStart) {
4440                Slog.w(TAG, "Pending start of voice interaction already.");
4441                return;
4442            }
4443            activity.pendingVoiceInteractionStart = true;
4444        }
4445        LocalServices.getService(VoiceInteractionManagerInternal.class)
4446                .startLocalVoiceInteraction(callingActivity, options);
4447    }
4448
4449    @Override
4450    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4451        LocalServices.getService(VoiceInteractionManagerInternal.class)
4452                .stopLocalVoiceInteraction(callingActivity);
4453    }
4454
4455    @Override
4456    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4457        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4458                .supportsLocalVoiceInteraction();
4459    }
4460
4461    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4462            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4463        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4464        if (activityToCallback == null) return;
4465        activityToCallback.setVoiceSessionLocked(voiceSession);
4466
4467        // Inform the activity
4468        try {
4469            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4470                    voiceInteractor);
4471            long token = Binder.clearCallingIdentity();
4472            try {
4473                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4474            } finally {
4475                Binder.restoreCallingIdentity(token);
4476            }
4477            // TODO: VI Should we cache the activity so that it's easier to find later
4478            // rather than scan through all the stacks and activities?
4479        } catch (RemoteException re) {
4480            activityToCallback.clearVoiceSessionLocked();
4481            // TODO: VI Should this terminate the voice session?
4482        }
4483    }
4484
4485    @Override
4486    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4487        synchronized (this) {
4488            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4489                if (keepAwake) {
4490                    mVoiceWakeLock.acquire();
4491                } else {
4492                    mVoiceWakeLock.release();
4493                }
4494            }
4495        }
4496    }
4497
4498    @Override
4499    public boolean startNextMatchingActivity(IBinder callingActivity,
4500            Intent intent, Bundle bOptions) {
4501        // Refuse possible leaked file descriptors
4502        if (intent != null && intent.hasFileDescriptors() == true) {
4503            throw new IllegalArgumentException("File descriptors passed in Intent");
4504        }
4505        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4506
4507        synchronized (this) {
4508            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4509            if (r == null) {
4510                ActivityOptions.abort(options);
4511                return false;
4512            }
4513            if (r.app == null || r.app.thread == null) {
4514                // The caller is not running...  d'oh!
4515                ActivityOptions.abort(options);
4516                return false;
4517            }
4518            intent = new Intent(intent);
4519            // The caller is not allowed to change the data.
4520            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4521            // And we are resetting to find the next component...
4522            intent.setComponent(null);
4523
4524            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4525
4526            ActivityInfo aInfo = null;
4527            try {
4528                List<ResolveInfo> resolves =
4529                    AppGlobals.getPackageManager().queryIntentActivities(
4530                            intent, r.resolvedType,
4531                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4532                            UserHandle.getCallingUserId()).getList();
4533
4534                // Look for the original activity in the list...
4535                final int N = resolves != null ? resolves.size() : 0;
4536                for (int i=0; i<N; i++) {
4537                    ResolveInfo rInfo = resolves.get(i);
4538                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4539                            && rInfo.activityInfo.name.equals(r.info.name)) {
4540                        // We found the current one...  the next matching is
4541                        // after it.
4542                        i++;
4543                        if (i<N) {
4544                            aInfo = resolves.get(i).activityInfo;
4545                        }
4546                        if (debug) {
4547                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4548                                    + "/" + r.info.name);
4549                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4550                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4551                        }
4552                        break;
4553                    }
4554                }
4555            } catch (RemoteException e) {
4556            }
4557
4558            if (aInfo == null) {
4559                // Nobody who is next!
4560                ActivityOptions.abort(options);
4561                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4562                return false;
4563            }
4564
4565            intent.setComponent(new ComponentName(
4566                    aInfo.applicationInfo.packageName, aInfo.name));
4567            intent.setFlags(intent.getFlags()&~(
4568                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4569                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4570                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4571                    Intent.FLAG_ACTIVITY_NEW_TASK));
4572
4573            // Okay now we need to start the new activity, replacing the
4574            // currently running activity.  This is a little tricky because
4575            // we want to start the new one as if the current one is finished,
4576            // but not finish the current one first so that there is no flicker.
4577            // And thus...
4578            final boolean wasFinishing = r.finishing;
4579            r.finishing = true;
4580
4581            // Propagate reply information over to the new activity.
4582            final ActivityRecord resultTo = r.resultTo;
4583            final String resultWho = r.resultWho;
4584            final int requestCode = r.requestCode;
4585            r.resultTo = null;
4586            if (resultTo != null) {
4587                resultTo.removeResultsLocked(r, resultWho, requestCode);
4588            }
4589
4590            final long origId = Binder.clearCallingIdentity();
4591            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4592                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4593                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4594                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4595                    false, false, null, null, null);
4596            Binder.restoreCallingIdentity(origId);
4597
4598            r.finishing = wasFinishing;
4599            if (res != ActivityManager.START_SUCCESS) {
4600                return false;
4601            }
4602            return true;
4603        }
4604    }
4605
4606    @Override
4607    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4608        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4609            String msg = "Permission Denial: startActivityFromRecents called without " +
4610                    START_TASKS_FROM_RECENTS;
4611            Slog.w(TAG, msg);
4612            throw new SecurityException(msg);
4613        }
4614        final long origId = Binder.clearCallingIdentity();
4615        try {
4616            synchronized (this) {
4617                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4618            }
4619        } finally {
4620            Binder.restoreCallingIdentity(origId);
4621        }
4622    }
4623
4624    final int startActivityInPackage(int uid, String callingPackage,
4625            Intent intent, String resolvedType, IBinder resultTo,
4626            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4627            IActivityContainer container, TaskRecord inTask) {
4628
4629        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4630                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4631
4632        // TODO: Switch to user app stacks here.
4633        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4634                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4635                null, null, null, bOptions, false, userId, container, inTask);
4636        return ret;
4637    }
4638
4639    @Override
4640    public final int startActivities(IApplicationThread caller, String callingPackage,
4641            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4642            int userId) {
4643        enforceNotIsolatedCaller("startActivities");
4644        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4645                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4646        // TODO: Switch to user app stacks here.
4647        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4648                resolvedTypes, resultTo, bOptions, userId);
4649        return ret;
4650    }
4651
4652    final int startActivitiesInPackage(int uid, String callingPackage,
4653            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4654            Bundle bOptions, int userId) {
4655
4656        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4657                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4658        // TODO: Switch to user app stacks here.
4659        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4660                resultTo, bOptions, userId);
4661        return ret;
4662    }
4663
4664    @Override
4665    public void reportActivityFullyDrawn(IBinder token) {
4666        synchronized (this) {
4667            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4668            if (r == null) {
4669                return;
4670            }
4671            r.reportFullyDrawnLocked();
4672        }
4673    }
4674
4675    @Override
4676    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4677        synchronized (this) {
4678            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4679            if (r == null) {
4680                return;
4681            }
4682            TaskRecord task = r.task;
4683            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4684                // Fixed screen orientation isn't supported when activities aren't in full screen
4685                // mode.
4686                return;
4687            }
4688            final long origId = Binder.clearCallingIdentity();
4689            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4690            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4691                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4692            if (config != null) {
4693                r.frozenBeforeDestroy = true;
4694                if (!updateConfigurationLocked(config, r, false)) {
4695                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4696                }
4697            }
4698            Binder.restoreCallingIdentity(origId);
4699        }
4700    }
4701
4702    @Override
4703    public int getRequestedOrientation(IBinder token) {
4704        synchronized (this) {
4705            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4706            if (r == null) {
4707                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4708            }
4709            return mWindowManager.getAppOrientation(r.appToken);
4710        }
4711    }
4712
4713    /**
4714     * This is the internal entry point for handling Activity.finish().
4715     *
4716     * @param token The Binder token referencing the Activity we want to finish.
4717     * @param resultCode Result code, if any, from this Activity.
4718     * @param resultData Result data (Intent), if any, from this Activity.
4719     * @param finishTask Whether to finish the task associated with this Activity.
4720     *
4721     * @return Returns true if the activity successfully finished, or false if it is still running.
4722     */
4723    @Override
4724    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4725            int finishTask) {
4726        // Refuse possible leaked file descriptors
4727        if (resultData != null && resultData.hasFileDescriptors() == true) {
4728            throw new IllegalArgumentException("File descriptors passed in Intent");
4729        }
4730
4731        synchronized(this) {
4732            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4733            if (r == null) {
4734                return true;
4735            }
4736            // Keep track of the root activity of the task before we finish it
4737            TaskRecord tr = r.task;
4738            ActivityRecord rootR = tr.getRootActivity();
4739            if (rootR == null) {
4740                Slog.w(TAG, "Finishing task with all activities already finished");
4741            }
4742            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4743            // finish.
4744            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4745                    mStackSupervisor.isLastLockedTask(tr)) {
4746                Slog.i(TAG, "Not finishing task in lock task mode");
4747                mStackSupervisor.showLockTaskToast();
4748                return false;
4749            }
4750            if (mController != null) {
4751                // Find the first activity that is not finishing.
4752                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4753                if (next != null) {
4754                    // ask watcher if this is allowed
4755                    boolean resumeOK = true;
4756                    try {
4757                        resumeOK = mController.activityResuming(next.packageName);
4758                    } catch (RemoteException e) {
4759                        mController = null;
4760                        Watchdog.getInstance().setActivityController(null);
4761                    }
4762
4763                    if (!resumeOK) {
4764                        Slog.i(TAG, "Not finishing activity because controller resumed");
4765                        return false;
4766                    }
4767                }
4768            }
4769            final long origId = Binder.clearCallingIdentity();
4770            try {
4771                boolean res;
4772                final boolean finishWithRootActivity =
4773                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4774                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4775                        || (finishWithRootActivity && r == rootR)) {
4776                    // If requested, remove the task that is associated to this activity only if it
4777                    // was the root activity in the task. The result code and data is ignored
4778                    // because we don't support returning them across task boundaries. Also, to
4779                    // keep backwards compatibility we remove the task from recents when finishing
4780                    // task with root activity.
4781                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4782                    if (!res) {
4783                        Slog.i(TAG, "Removing task failed to finish activity");
4784                    }
4785                } else {
4786                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4787                            resultData, "app-request", true);
4788                    if (!res) {
4789                        Slog.i(TAG, "Failed to finish by app-request");
4790                    }
4791                }
4792                return res;
4793            } finally {
4794                Binder.restoreCallingIdentity(origId);
4795            }
4796        }
4797    }
4798
4799    @Override
4800    public final void finishHeavyWeightApp() {
4801        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4802                != PackageManager.PERMISSION_GRANTED) {
4803            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4804                    + Binder.getCallingPid()
4805                    + ", uid=" + Binder.getCallingUid()
4806                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4807            Slog.w(TAG, msg);
4808            throw new SecurityException(msg);
4809        }
4810
4811        synchronized(this) {
4812            if (mHeavyWeightProcess == null) {
4813                return;
4814            }
4815
4816            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4817            for (int i = 0; i < activities.size(); i++) {
4818                ActivityRecord r = activities.get(i);
4819                if (!r.finishing && r.isInStackLocked()) {
4820                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4821                            null, "finish-heavy", true);
4822                }
4823            }
4824
4825            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4826                    mHeavyWeightProcess.userId, 0));
4827            mHeavyWeightProcess = null;
4828        }
4829    }
4830
4831    @Override
4832    public void crashApplication(int uid, int initialPid, String packageName,
4833            String message) {
4834        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4835                != PackageManager.PERMISSION_GRANTED) {
4836            String msg = "Permission Denial: crashApplication() from pid="
4837                    + Binder.getCallingPid()
4838                    + ", uid=" + Binder.getCallingUid()
4839                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4840            Slog.w(TAG, msg);
4841            throw new SecurityException(msg);
4842        }
4843
4844        synchronized(this) {
4845            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4846        }
4847    }
4848
4849    @Override
4850    public final void finishSubActivity(IBinder token, String resultWho,
4851            int requestCode) {
4852        synchronized(this) {
4853            final long origId = Binder.clearCallingIdentity();
4854            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4855            if (r != null) {
4856                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4857            }
4858            Binder.restoreCallingIdentity(origId);
4859        }
4860    }
4861
4862    @Override
4863    public boolean finishActivityAffinity(IBinder token) {
4864        synchronized(this) {
4865            final long origId = Binder.clearCallingIdentity();
4866            try {
4867                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4868                if (r == null) {
4869                    return false;
4870                }
4871
4872                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4873                // can finish.
4874                final TaskRecord task = r.task;
4875                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4876                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4877                    mStackSupervisor.showLockTaskToast();
4878                    return false;
4879                }
4880                return task.stack.finishActivityAffinityLocked(r);
4881            } finally {
4882                Binder.restoreCallingIdentity(origId);
4883            }
4884        }
4885    }
4886
4887    @Override
4888    public void finishVoiceTask(IVoiceInteractionSession session) {
4889        synchronized (this) {
4890            final long origId = Binder.clearCallingIdentity();
4891            try {
4892                // TODO: VI Consider treating local voice interactions and voice tasks
4893                // differently here
4894                mStackSupervisor.finishVoiceTask(session);
4895            } finally {
4896                Binder.restoreCallingIdentity(origId);
4897            }
4898        }
4899
4900    }
4901
4902    @Override
4903    public boolean releaseActivityInstance(IBinder token) {
4904        synchronized(this) {
4905            final long origId = Binder.clearCallingIdentity();
4906            try {
4907                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4908                if (r == null) {
4909                    return false;
4910                }
4911                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4912            } finally {
4913                Binder.restoreCallingIdentity(origId);
4914            }
4915        }
4916    }
4917
4918    @Override
4919    public void releaseSomeActivities(IApplicationThread appInt) {
4920        synchronized(this) {
4921            final long origId = Binder.clearCallingIdentity();
4922            try {
4923                ProcessRecord app = getRecordForAppLocked(appInt);
4924                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4925            } finally {
4926                Binder.restoreCallingIdentity(origId);
4927            }
4928        }
4929    }
4930
4931    @Override
4932    public boolean willActivityBeVisible(IBinder token) {
4933        synchronized(this) {
4934            ActivityStack stack = ActivityRecord.getStackLocked(token);
4935            if (stack != null) {
4936                return stack.willActivityBeVisibleLocked(token);
4937            }
4938            return false;
4939        }
4940    }
4941
4942    @Override
4943    public void overridePendingTransition(IBinder token, String packageName,
4944            int enterAnim, int exitAnim) {
4945        synchronized(this) {
4946            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4947            if (self == null) {
4948                return;
4949            }
4950
4951            final long origId = Binder.clearCallingIdentity();
4952
4953            if (self.state == ActivityState.RESUMED
4954                    || self.state == ActivityState.PAUSING) {
4955                mWindowManager.overridePendingAppTransition(packageName,
4956                        enterAnim, exitAnim, null);
4957            }
4958
4959            Binder.restoreCallingIdentity(origId);
4960        }
4961    }
4962
4963    /**
4964     * Main function for removing an existing process from the activity manager
4965     * as a result of that process going away.  Clears out all connections
4966     * to the process.
4967     */
4968    private final void handleAppDiedLocked(ProcessRecord app,
4969            boolean restarting, boolean allowRestart) {
4970        int pid = app.pid;
4971        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4972        if (!kept && !restarting) {
4973            removeLruProcessLocked(app);
4974            if (pid > 0) {
4975                ProcessList.remove(pid);
4976            }
4977        }
4978
4979        if (mProfileProc == app) {
4980            clearProfilerLocked();
4981        }
4982
4983        // Remove this application's activities from active lists.
4984        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4985
4986        app.activities.clear();
4987
4988        if (app.instrumentationClass != null) {
4989            Slog.w(TAG, "Crash of app " + app.processName
4990                  + " running instrumentation " + app.instrumentationClass);
4991            Bundle info = new Bundle();
4992            info.putString("shortMsg", "Process crashed.");
4993            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4994        }
4995
4996        if (!restarting && hasVisibleActivities
4997                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
4998            // If there was nothing to resume, and we are not already restarting this process, but
4999            // there is a visible activity that is hosted by the process...  then make sure all
5000            // visible activities are running, taking care of restarting this process.
5001            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5002        }
5003    }
5004
5005    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5006        IBinder threadBinder = thread.asBinder();
5007        // Find the application record.
5008        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5009            ProcessRecord rec = mLruProcesses.get(i);
5010            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5011                return i;
5012            }
5013        }
5014        return -1;
5015    }
5016
5017    final ProcessRecord getRecordForAppLocked(
5018            IApplicationThread thread) {
5019        if (thread == null) {
5020            return null;
5021        }
5022
5023        int appIndex = getLRURecordIndexForAppLocked(thread);
5024        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5025    }
5026
5027    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5028        // If there are no longer any background processes running,
5029        // and the app that died was not running instrumentation,
5030        // then tell everyone we are now low on memory.
5031        boolean haveBg = false;
5032        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5033            ProcessRecord rec = mLruProcesses.get(i);
5034            if (rec.thread != null
5035                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5036                haveBg = true;
5037                break;
5038            }
5039        }
5040
5041        if (!haveBg) {
5042            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5043            if (doReport) {
5044                long now = SystemClock.uptimeMillis();
5045                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5046                    doReport = false;
5047                } else {
5048                    mLastMemUsageReportTime = now;
5049                }
5050            }
5051            final ArrayList<ProcessMemInfo> memInfos
5052                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5053            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5054            long now = SystemClock.uptimeMillis();
5055            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5056                ProcessRecord rec = mLruProcesses.get(i);
5057                if (rec == dyingProc || rec.thread == null) {
5058                    continue;
5059                }
5060                if (doReport) {
5061                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5062                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5063                }
5064                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5065                    // The low memory report is overriding any current
5066                    // state for a GC request.  Make sure to do
5067                    // heavy/important/visible/foreground processes first.
5068                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5069                        rec.lastRequestedGc = 0;
5070                    } else {
5071                        rec.lastRequestedGc = rec.lastLowMemory;
5072                    }
5073                    rec.reportLowMemory = true;
5074                    rec.lastLowMemory = now;
5075                    mProcessesToGc.remove(rec);
5076                    addProcessToGcListLocked(rec);
5077                }
5078            }
5079            if (doReport) {
5080                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5081                mHandler.sendMessage(msg);
5082            }
5083            scheduleAppGcsLocked();
5084        }
5085    }
5086
5087    final void appDiedLocked(ProcessRecord app) {
5088       appDiedLocked(app, app.pid, app.thread, false);
5089    }
5090
5091    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5092            boolean fromBinderDied) {
5093        // First check if this ProcessRecord is actually active for the pid.
5094        synchronized (mPidsSelfLocked) {
5095            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5096            if (curProc != app) {
5097                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5098                return;
5099            }
5100        }
5101
5102        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5103        synchronized (stats) {
5104            stats.noteProcessDiedLocked(app.info.uid, pid);
5105        }
5106
5107        if (!app.killed) {
5108            if (!fromBinderDied) {
5109                Process.killProcessQuiet(pid);
5110            }
5111            killProcessGroup(app.uid, pid);
5112            app.killed = true;
5113        }
5114
5115        // Clean up already done if the process has been re-started.
5116        if (app.pid == pid && app.thread != null &&
5117                app.thread.asBinder() == thread.asBinder()) {
5118            boolean doLowMem = app.instrumentationClass == null;
5119            boolean doOomAdj = doLowMem;
5120            if (!app.killedByAm) {
5121                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5122                        + ") has died");
5123                mAllowLowerMemLevel = true;
5124            } else {
5125                // Note that we always want to do oom adj to update our state with the
5126                // new number of procs.
5127                mAllowLowerMemLevel = false;
5128                doLowMem = false;
5129            }
5130            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5131            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5132                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5133            handleAppDiedLocked(app, false, true);
5134
5135            if (doOomAdj) {
5136                updateOomAdjLocked();
5137            }
5138            if (doLowMem) {
5139                doLowMemReportIfNeededLocked(app);
5140            }
5141        } else if (app.pid != pid) {
5142            // A new process has already been started.
5143            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5144                    + ") has died and restarted (pid " + app.pid + ").");
5145            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5146        } else if (DEBUG_PROCESSES) {
5147            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5148                    + thread.asBinder());
5149        }
5150    }
5151
5152    /**
5153     * If a stack trace dump file is configured, dump process stack traces.
5154     * @param clearTraces causes the dump file to be erased prior to the new
5155     *    traces being written, if true; when false, the new traces will be
5156     *    appended to any existing file content.
5157     * @param firstPids of dalvik VM processes to dump stack traces for first
5158     * @param lastPids of dalvik VM processes to dump stack traces for last
5159     * @param nativeProcs optional list of native process names to dump stack crawls
5160     * @return file containing stack traces, or null if no dump file is configured
5161     */
5162    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5163            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5164        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5165        if (tracesPath == null || tracesPath.length() == 0) {
5166            return null;
5167        }
5168
5169        File tracesFile = new File(tracesPath);
5170        try {
5171            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5172            tracesFile.createNewFile();
5173            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5174        } catch (IOException e) {
5175            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5176            return null;
5177        }
5178
5179        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5180        return tracesFile;
5181    }
5182
5183    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5184            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5185        // Use a FileObserver to detect when traces finish writing.
5186        // The order of traces is considered important to maintain for legibility.
5187        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5188            @Override
5189            public synchronized void onEvent(int event, String path) { notify(); }
5190        };
5191
5192        try {
5193            observer.startWatching();
5194
5195            // First collect all of the stacks of the most important pids.
5196            if (firstPids != null) {
5197                try {
5198                    int num = firstPids.size();
5199                    for (int i = 0; i < num; i++) {
5200                        synchronized (observer) {
5201                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5202                                    + firstPids.get(i));
5203                            final long sime = SystemClock.elapsedRealtime();
5204                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5205                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5206                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5207                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5208                        }
5209                    }
5210                } catch (InterruptedException e) {
5211                    Slog.wtf(TAG, e);
5212                }
5213            }
5214
5215            // Next collect the stacks of the native pids
5216            if (nativeProcs != null) {
5217                int[] pids = Process.getPidsForCommands(nativeProcs);
5218                if (pids != null) {
5219                    for (int pid : pids) {
5220                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5221                        final long sime = SystemClock.elapsedRealtime();
5222                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5223                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5224                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5225                    }
5226                }
5227            }
5228
5229            // Lastly, measure CPU usage.
5230            if (processCpuTracker != null) {
5231                processCpuTracker.init();
5232                System.gc();
5233                processCpuTracker.update();
5234                try {
5235                    synchronized (processCpuTracker) {
5236                        processCpuTracker.wait(500); // measure over 1/2 second.
5237                    }
5238                } catch (InterruptedException e) {
5239                }
5240                processCpuTracker.update();
5241
5242                // We'll take the stack crawls of just the top apps using CPU.
5243                final int N = processCpuTracker.countWorkingStats();
5244                int numProcs = 0;
5245                for (int i=0; i<N && numProcs<5; i++) {
5246                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5247                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5248                        numProcs++;
5249                        try {
5250                            synchronized (observer) {
5251                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5252                                        + stats.pid);
5253                                final long stime = SystemClock.elapsedRealtime();
5254                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5255                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5256                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5257                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5258                            }
5259                        } catch (InterruptedException e) {
5260                            Slog.wtf(TAG, e);
5261                        }
5262                    } else if (DEBUG_ANR) {
5263                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5264                                + stats.pid);
5265                    }
5266                }
5267            }
5268        } finally {
5269            observer.stopWatching();
5270        }
5271    }
5272
5273    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5274        if (true || IS_USER_BUILD) {
5275            return;
5276        }
5277        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5278        if (tracesPath == null || tracesPath.length() == 0) {
5279            return;
5280        }
5281
5282        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5283        StrictMode.allowThreadDiskWrites();
5284        try {
5285            final File tracesFile = new File(tracesPath);
5286            final File tracesDir = tracesFile.getParentFile();
5287            final File tracesTmp = new File(tracesDir, "__tmp__");
5288            try {
5289                if (tracesFile.exists()) {
5290                    tracesTmp.delete();
5291                    tracesFile.renameTo(tracesTmp);
5292                }
5293                StringBuilder sb = new StringBuilder();
5294                Time tobj = new Time();
5295                tobj.set(System.currentTimeMillis());
5296                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5297                sb.append(": ");
5298                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5299                sb.append(" since ");
5300                sb.append(msg);
5301                FileOutputStream fos = new FileOutputStream(tracesFile);
5302                fos.write(sb.toString().getBytes());
5303                if (app == null) {
5304                    fos.write("\n*** No application process!".getBytes());
5305                }
5306                fos.close();
5307                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5308            } catch (IOException e) {
5309                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5310                return;
5311            }
5312
5313            if (app != null) {
5314                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5315                firstPids.add(app.pid);
5316                dumpStackTraces(tracesPath, firstPids, null, null, null);
5317            }
5318
5319            File lastTracesFile = null;
5320            File curTracesFile = null;
5321            for (int i=9; i>=0; i--) {
5322                String name = String.format(Locale.US, "slow%02d.txt", i);
5323                curTracesFile = new File(tracesDir, name);
5324                if (curTracesFile.exists()) {
5325                    if (lastTracesFile != null) {
5326                        curTracesFile.renameTo(lastTracesFile);
5327                    } else {
5328                        curTracesFile.delete();
5329                    }
5330                }
5331                lastTracesFile = curTracesFile;
5332            }
5333            tracesFile.renameTo(curTracesFile);
5334            if (tracesTmp.exists()) {
5335                tracesTmp.renameTo(tracesFile);
5336            }
5337        } finally {
5338            StrictMode.setThreadPolicy(oldPolicy);
5339        }
5340    }
5341
5342    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5343        if (!mLaunchWarningShown) {
5344            mLaunchWarningShown = true;
5345            mUiHandler.post(new Runnable() {
5346                @Override
5347                public void run() {
5348                    synchronized (ActivityManagerService.this) {
5349                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5350                        d.show();
5351                        mUiHandler.postDelayed(new Runnable() {
5352                            @Override
5353                            public void run() {
5354                                synchronized (ActivityManagerService.this) {
5355                                    d.dismiss();
5356                                    mLaunchWarningShown = false;
5357                                }
5358                            }
5359                        }, 4000);
5360                    }
5361                }
5362            });
5363        }
5364    }
5365
5366    @Override
5367    public boolean clearApplicationUserData(final String packageName,
5368            final IPackageDataObserver observer, int userId) {
5369        enforceNotIsolatedCaller("clearApplicationUserData");
5370        int uid = Binder.getCallingUid();
5371        int pid = Binder.getCallingPid();
5372        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5373                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5374
5375        final DevicePolicyManagerInternal dpmi = LocalServices
5376                .getService(DevicePolicyManagerInternal.class);
5377        if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) {
5378            throw new SecurityException("Cannot clear data for a device owner or a profile owner");
5379        }
5380
5381        long callingId = Binder.clearCallingIdentity();
5382        try {
5383            IPackageManager pm = AppGlobals.getPackageManager();
5384            int pkgUid = -1;
5385            synchronized(this) {
5386                try {
5387                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5388                } catch (RemoteException e) {
5389                }
5390                if (pkgUid == -1) {
5391                    Slog.w(TAG, "Invalid packageName: " + packageName);
5392                    if (observer != null) {
5393                        try {
5394                            observer.onRemoveCompleted(packageName, false);
5395                        } catch (RemoteException e) {
5396                            Slog.i(TAG, "Observer no longer exists.");
5397                        }
5398                    }
5399                    return false;
5400                }
5401                if (uid == pkgUid || checkComponentPermission(
5402                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5403                        pid, uid, -1, true)
5404                        == PackageManager.PERMISSION_GRANTED) {
5405                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5406                } else {
5407                    throw new SecurityException("PID " + pid + " does not have permission "
5408                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5409                                    + " of package " + packageName);
5410                }
5411
5412                // Remove all tasks match the cleared application package and user
5413                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5414                    final TaskRecord tr = mRecentTasks.get(i);
5415                    final String taskPackageName =
5416                            tr.getBaseIntent().getComponent().getPackageName();
5417                    if (tr.userId != userId) continue;
5418                    if (!taskPackageName.equals(packageName)) continue;
5419                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5420                }
5421            }
5422
5423            final int pkgUidF = pkgUid;
5424            final int userIdF = userId;
5425            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5426                @Override
5427                public void onRemoveCompleted(String packageName, boolean succeeded)
5428                        throws RemoteException {
5429                    synchronized (ActivityManagerService.this) {
5430                        finishForceStopPackageLocked(packageName, pkgUidF);
5431                    }
5432
5433                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5434                            Uri.fromParts("package", packageName, null));
5435                    intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5436                    intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5437                    broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5438                            null, null, 0, null, null, null, null, false, false, userIdF);
5439
5440                    if (observer != null) {
5441                        observer.onRemoveCompleted(packageName, succeeded);
5442                    }
5443                }
5444            };
5445
5446            try {
5447                // Clear application user data
5448                pm.clearApplicationUserData(packageName, localObserver, userId);
5449
5450                synchronized(this) {
5451                    // Remove all permissions granted from/to this package
5452                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5453                }
5454
5455                // Remove all zen rules created by this package; revoke it's zen access.
5456                INotificationManager inm = NotificationManager.getService();
5457                inm.removeAutomaticZenRules(packageName);
5458                inm.setNotificationPolicyAccessGranted(packageName, false);
5459
5460            } catch (RemoteException e) {
5461            }
5462        } finally {
5463            Binder.restoreCallingIdentity(callingId);
5464        }
5465        return true;
5466    }
5467
5468    @Override
5469    public void killBackgroundProcesses(final String packageName, int userId) {
5470        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5471                != PackageManager.PERMISSION_GRANTED &&
5472                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5473                        != PackageManager.PERMISSION_GRANTED) {
5474            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5475                    + Binder.getCallingPid()
5476                    + ", uid=" + Binder.getCallingUid()
5477                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5478            Slog.w(TAG, msg);
5479            throw new SecurityException(msg);
5480        }
5481
5482        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5483                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5484        long callingId = Binder.clearCallingIdentity();
5485        try {
5486            IPackageManager pm = AppGlobals.getPackageManager();
5487            synchronized(this) {
5488                int appId = -1;
5489                try {
5490                    appId = UserHandle.getAppId(
5491                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5492                } catch (RemoteException e) {
5493                }
5494                if (appId == -1) {
5495                    Slog.w(TAG, "Invalid packageName: " + packageName);
5496                    return;
5497                }
5498                killPackageProcessesLocked(packageName, appId, userId,
5499                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5500            }
5501        } finally {
5502            Binder.restoreCallingIdentity(callingId);
5503        }
5504    }
5505
5506    @Override
5507    public void killAllBackgroundProcesses() {
5508        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5509                != PackageManager.PERMISSION_GRANTED) {
5510            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5511                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5512                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5513            Slog.w(TAG, msg);
5514            throw new SecurityException(msg);
5515        }
5516
5517        final long callingId = Binder.clearCallingIdentity();
5518        try {
5519            synchronized (this) {
5520                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5521                final int NP = mProcessNames.getMap().size();
5522                for (int ip = 0; ip < NP; ip++) {
5523                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5524                    final int NA = apps.size();
5525                    for (int ia = 0; ia < NA; ia++) {
5526                        final ProcessRecord app = apps.valueAt(ia);
5527                        if (app.persistent) {
5528                            // We don't kill persistent processes.
5529                            continue;
5530                        }
5531                        if (app.removed) {
5532                            procs.add(app);
5533                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5534                            app.removed = true;
5535                            procs.add(app);
5536                        }
5537                    }
5538                }
5539
5540                final int N = procs.size();
5541                for (int i = 0; i < N; i++) {
5542                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5543                }
5544
5545                mAllowLowerMemLevel = true;
5546
5547                updateOomAdjLocked();
5548                doLowMemReportIfNeededLocked(null);
5549            }
5550        } finally {
5551            Binder.restoreCallingIdentity(callingId);
5552        }
5553    }
5554
5555    /**
5556     * Kills all background processes, except those matching any of the
5557     * specified properties.
5558     *
5559     * @param minTargetSdk the target SDK version at or above which to preserve
5560     *                     processes, or {@code -1} to ignore the target SDK
5561     * @param maxProcState the process state at or below which to preserve
5562     *                     processes, or {@code -1} to ignore the process state
5563     */
5564    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5565        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5566                != PackageManager.PERMISSION_GRANTED) {
5567            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5568                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5569                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5570            Slog.w(TAG, msg);
5571            throw new SecurityException(msg);
5572        }
5573
5574        final long callingId = Binder.clearCallingIdentity();
5575        try {
5576            synchronized (this) {
5577                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5578                final int NP = mProcessNames.getMap().size();
5579                for (int ip = 0; ip < NP; ip++) {
5580                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5581                    final int NA = apps.size();
5582                    for (int ia = 0; ia < NA; ia++) {
5583                        final ProcessRecord app = apps.valueAt(ia);
5584                        if (app.removed) {
5585                            procs.add(app);
5586                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5587                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5588                            app.removed = true;
5589                            procs.add(app);
5590                        }
5591                    }
5592                }
5593
5594                final int N = procs.size();
5595                for (int i = 0; i < N; i++) {
5596                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5597                }
5598            }
5599        } finally {
5600            Binder.restoreCallingIdentity(callingId);
5601        }
5602    }
5603
5604    @Override
5605    public void forceStopPackage(final String packageName, int userId) {
5606        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5607                != PackageManager.PERMISSION_GRANTED) {
5608            String msg = "Permission Denial: forceStopPackage() from pid="
5609                    + Binder.getCallingPid()
5610                    + ", uid=" + Binder.getCallingUid()
5611                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5612            Slog.w(TAG, msg);
5613            throw new SecurityException(msg);
5614        }
5615        final int callingPid = Binder.getCallingPid();
5616        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5617                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5618        long callingId = Binder.clearCallingIdentity();
5619        try {
5620            IPackageManager pm = AppGlobals.getPackageManager();
5621            synchronized(this) {
5622                int[] users = userId == UserHandle.USER_ALL
5623                        ? mUserController.getUsers() : new int[] { userId };
5624                for (int user : users) {
5625                    int pkgUid = -1;
5626                    try {
5627                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5628                                user);
5629                    } catch (RemoteException e) {
5630                    }
5631                    if (pkgUid == -1) {
5632                        Slog.w(TAG, "Invalid packageName: " + packageName);
5633                        continue;
5634                    }
5635                    try {
5636                        pm.setPackageStoppedState(packageName, true, user);
5637                    } catch (RemoteException e) {
5638                    } catch (IllegalArgumentException e) {
5639                        Slog.w(TAG, "Failed trying to unstop package "
5640                                + packageName + ": " + e);
5641                    }
5642                    if (mUserController.isUserRunningLocked(user, 0)) {
5643                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5644                        finishForceStopPackageLocked(packageName, pkgUid);
5645                    }
5646                }
5647            }
5648        } finally {
5649            Binder.restoreCallingIdentity(callingId);
5650        }
5651    }
5652
5653    @Override
5654    public void addPackageDependency(String packageName) {
5655        synchronized (this) {
5656            int callingPid = Binder.getCallingPid();
5657            if (callingPid == Process.myPid()) {
5658                //  Yeah, um, no.
5659                return;
5660            }
5661            ProcessRecord proc;
5662            synchronized (mPidsSelfLocked) {
5663                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5664            }
5665            if (proc != null) {
5666                if (proc.pkgDeps == null) {
5667                    proc.pkgDeps = new ArraySet<String>(1);
5668                }
5669                proc.pkgDeps.add(packageName);
5670            }
5671        }
5672    }
5673
5674    /*
5675     * The pkg name and app id have to be specified.
5676     */
5677    @Override
5678    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5679        if (pkg == null) {
5680            return;
5681        }
5682        // Make sure the uid is valid.
5683        if (appid < 0) {
5684            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5685            return;
5686        }
5687        int callerUid = Binder.getCallingUid();
5688        // Only the system server can kill an application
5689        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5690            // Post an aysnc message to kill the application
5691            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5692            msg.arg1 = appid;
5693            msg.arg2 = 0;
5694            Bundle bundle = new Bundle();
5695            bundle.putString("pkg", pkg);
5696            bundle.putString("reason", reason);
5697            msg.obj = bundle;
5698            mHandler.sendMessage(msg);
5699        } else {
5700            throw new SecurityException(callerUid + " cannot kill pkg: " +
5701                    pkg);
5702        }
5703    }
5704
5705    @Override
5706    public void closeSystemDialogs(String reason) {
5707        enforceNotIsolatedCaller("closeSystemDialogs");
5708
5709        final int pid = Binder.getCallingPid();
5710        final int uid = Binder.getCallingUid();
5711        final long origId = Binder.clearCallingIdentity();
5712        try {
5713            synchronized (this) {
5714                // Only allow this from foreground processes, so that background
5715                // applications can't abuse it to prevent system UI from being shown.
5716                if (uid >= Process.FIRST_APPLICATION_UID) {
5717                    ProcessRecord proc;
5718                    synchronized (mPidsSelfLocked) {
5719                        proc = mPidsSelfLocked.get(pid);
5720                    }
5721                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5722                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5723                                + " from background process " + proc);
5724                        return;
5725                    }
5726                }
5727                closeSystemDialogsLocked(reason);
5728            }
5729        } finally {
5730            Binder.restoreCallingIdentity(origId);
5731        }
5732    }
5733
5734    void closeSystemDialogsLocked(String reason) {
5735        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5736        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5737                | Intent.FLAG_RECEIVER_FOREGROUND);
5738        if (reason != null) {
5739            intent.putExtra("reason", reason);
5740        }
5741        mWindowManager.closeSystemDialogs(reason);
5742
5743        mStackSupervisor.closeSystemDialogsLocked();
5744
5745        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5746                AppOpsManager.OP_NONE, null, false, false,
5747                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5748    }
5749
5750    @Override
5751    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5752        enforceNotIsolatedCaller("getProcessMemoryInfo");
5753        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5754        for (int i=pids.length-1; i>=0; i--) {
5755            ProcessRecord proc;
5756            int oomAdj;
5757            synchronized (this) {
5758                synchronized (mPidsSelfLocked) {
5759                    proc = mPidsSelfLocked.get(pids[i]);
5760                    oomAdj = proc != null ? proc.setAdj : 0;
5761                }
5762            }
5763            infos[i] = new Debug.MemoryInfo();
5764            Debug.getMemoryInfo(pids[i], infos[i]);
5765            if (proc != null) {
5766                synchronized (this) {
5767                    if (proc.thread != null && proc.setAdj == oomAdj) {
5768                        // Record this for posterity if the process has been stable.
5769                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5770                                infos[i].getTotalUss(), false, proc.pkgList);
5771                    }
5772                }
5773            }
5774        }
5775        return infos;
5776    }
5777
5778    @Override
5779    public long[] getProcessPss(int[] pids) {
5780        enforceNotIsolatedCaller("getProcessPss");
5781        long[] pss = new long[pids.length];
5782        for (int i=pids.length-1; i>=0; i--) {
5783            ProcessRecord proc;
5784            int oomAdj;
5785            synchronized (this) {
5786                synchronized (mPidsSelfLocked) {
5787                    proc = mPidsSelfLocked.get(pids[i]);
5788                    oomAdj = proc != null ? proc.setAdj : 0;
5789                }
5790            }
5791            long[] tmpUss = new long[1];
5792            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5793            if (proc != null) {
5794                synchronized (this) {
5795                    if (proc.thread != null && proc.setAdj == oomAdj) {
5796                        // Record this for posterity if the process has been stable.
5797                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5798                    }
5799                }
5800            }
5801        }
5802        return pss;
5803    }
5804
5805    @Override
5806    public void killApplicationProcess(String processName, int uid) {
5807        if (processName == null) {
5808            return;
5809        }
5810
5811        int callerUid = Binder.getCallingUid();
5812        // Only the system server can kill an application
5813        if (callerUid == Process.SYSTEM_UID) {
5814            synchronized (this) {
5815                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5816                if (app != null && app.thread != null) {
5817                    try {
5818                        app.thread.scheduleSuicide();
5819                    } catch (RemoteException e) {
5820                        // If the other end already died, then our work here is done.
5821                    }
5822                } else {
5823                    Slog.w(TAG, "Process/uid not found attempting kill of "
5824                            + processName + " / " + uid);
5825                }
5826            }
5827        } else {
5828            throw new SecurityException(callerUid + " cannot kill app process: " +
5829                    processName);
5830        }
5831    }
5832
5833    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5834        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5835                false, true, false, false, UserHandle.getUserId(uid), reason);
5836    }
5837
5838    private void finishForceStopPackageLocked(final String packageName, int uid) {
5839        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5840                Uri.fromParts("package", packageName, null));
5841        if (!mProcessesReady) {
5842            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5843                    | Intent.FLAG_RECEIVER_FOREGROUND);
5844        }
5845        intent.putExtra(Intent.EXTRA_UID, uid);
5846        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5847        broadcastIntentLocked(null, null, intent,
5848                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5849                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5850    }
5851
5852
5853    private final boolean killPackageProcessesLocked(String packageName, int appId,
5854            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5855            boolean doit, boolean evenPersistent, String reason) {
5856        ArrayList<ProcessRecord> procs = new ArrayList<>();
5857
5858        // Remove all processes this package may have touched: all with the
5859        // same UID (except for the system or root user), and all whose name
5860        // matches the package name.
5861        final int NP = mProcessNames.getMap().size();
5862        for (int ip=0; ip<NP; ip++) {
5863            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5864            final int NA = apps.size();
5865            for (int ia=0; ia<NA; ia++) {
5866                ProcessRecord app = apps.valueAt(ia);
5867                if (app.persistent && !evenPersistent) {
5868                    // we don't kill persistent processes
5869                    continue;
5870                }
5871                if (app.removed) {
5872                    if (doit) {
5873                        procs.add(app);
5874                    }
5875                    continue;
5876                }
5877
5878                // Skip process if it doesn't meet our oom adj requirement.
5879                if (app.setAdj < minOomAdj) {
5880                    continue;
5881                }
5882
5883                // If no package is specified, we call all processes under the
5884                // give user id.
5885                if (packageName == null) {
5886                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5887                        continue;
5888                    }
5889                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5890                        continue;
5891                    }
5892                // Package has been specified, we want to hit all processes
5893                // that match it.  We need to qualify this by the processes
5894                // that are running under the specified app and user ID.
5895                } else {
5896                    final boolean isDep = app.pkgDeps != null
5897                            && app.pkgDeps.contains(packageName);
5898                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5899                        continue;
5900                    }
5901                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5902                        continue;
5903                    }
5904                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5905                        continue;
5906                    }
5907                }
5908
5909                // Process has passed all conditions, kill it!
5910                if (!doit) {
5911                    return true;
5912                }
5913                app.removed = true;
5914                procs.add(app);
5915            }
5916        }
5917
5918        int N = procs.size();
5919        for (int i=0; i<N; i++) {
5920            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5921        }
5922        updateOomAdjLocked();
5923        return N > 0;
5924    }
5925
5926    private void cleanupDisabledPackageComponentsLocked(
5927            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5928
5929        Set<String> disabledClasses = null;
5930        boolean packageDisabled = false;
5931        IPackageManager pm = AppGlobals.getPackageManager();
5932
5933        if (changedClasses == null) {
5934            // Nothing changed...
5935            return;
5936        }
5937
5938        // Determine enable/disable state of the package and its components.
5939        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5940        for (int i = changedClasses.length - 1; i >= 0; i--) {
5941            final String changedClass = changedClasses[i];
5942
5943            if (changedClass.equals(packageName)) {
5944                try {
5945                    // Entire package setting changed
5946                    enabled = pm.getApplicationEnabledSetting(packageName,
5947                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5948                } catch (Exception e) {
5949                    // No such package/component; probably racing with uninstall.  In any
5950                    // event it means we have nothing further to do here.
5951                    return;
5952                }
5953                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5954                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5955                if (packageDisabled) {
5956                    // Entire package is disabled.
5957                    // No need to continue to check component states.
5958                    disabledClasses = null;
5959                    break;
5960                }
5961            } else {
5962                try {
5963                    enabled = pm.getComponentEnabledSetting(
5964                            new ComponentName(packageName, changedClass),
5965                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5966                } catch (Exception e) {
5967                    // As above, probably racing with uninstall.
5968                    return;
5969                }
5970                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5971                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5972                    if (disabledClasses == null) {
5973                        disabledClasses = new ArraySet<>(changedClasses.length);
5974                    }
5975                    disabledClasses.add(changedClass);
5976                }
5977            }
5978        }
5979
5980        if (!packageDisabled && disabledClasses == null) {
5981            // Nothing to do here...
5982            return;
5983        }
5984
5985        // Clean-up disabled activities.
5986        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5987                packageName, disabledClasses, true, false, userId) && mBooted) {
5988            mStackSupervisor.resumeFocusedStackTopActivityLocked();
5989            mStackSupervisor.scheduleIdleLocked();
5990        }
5991
5992        // Clean-up disabled tasks
5993        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5994
5995        // Clean-up disabled services.
5996        mServices.bringDownDisabledPackageServicesLocked(
5997                packageName, disabledClasses, userId, false, killProcess, true);
5998
5999        // Clean-up disabled providers.
6000        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6001        mProviderMap.collectPackageProvidersLocked(
6002                packageName, disabledClasses, true, false, userId, providers);
6003        for (int i = providers.size() - 1; i >= 0; i--) {
6004            removeDyingProviderLocked(null, providers.get(i), true);
6005        }
6006
6007        // Clean-up disabled broadcast receivers.
6008        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6009            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6010                    packageName, disabledClasses, userId, true);
6011        }
6012
6013    }
6014
6015    final boolean clearBroadcastQueueForUserLocked(int userId) {
6016        boolean didSomething = false;
6017        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6018            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6019                    null, null, userId, true);
6020        }
6021        return didSomething;
6022    }
6023
6024    final boolean forceStopPackageLocked(String packageName, int appId,
6025            boolean callerWillRestart, boolean purgeCache, boolean doit,
6026            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6027        int i;
6028
6029        if (userId == UserHandle.USER_ALL && packageName == null) {
6030            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6031        }
6032
6033        if (appId < 0 && packageName != null) {
6034            try {
6035                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6036                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
6037            } catch (RemoteException e) {
6038            }
6039        }
6040
6041        if (doit) {
6042            if (packageName != null) {
6043                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6044                        + " user=" + userId + ": " + reason);
6045            } else {
6046                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6047            }
6048
6049            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6050        }
6051
6052        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6053                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6054                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6055
6056        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6057                packageName, null, doit, evenPersistent, userId)) {
6058            if (!doit) {
6059                return true;
6060            }
6061            didSomething = true;
6062        }
6063
6064        if (mServices.bringDownDisabledPackageServicesLocked(
6065                packageName, null, userId, evenPersistent, true, doit)) {
6066            if (!doit) {
6067                return true;
6068            }
6069            didSomething = true;
6070        }
6071
6072        if (packageName == null) {
6073            // Remove all sticky broadcasts from this user.
6074            mStickyBroadcasts.remove(userId);
6075        }
6076
6077        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6078        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6079                userId, providers)) {
6080            if (!doit) {
6081                return true;
6082            }
6083            didSomething = true;
6084        }
6085        for (i = providers.size() - 1; i >= 0; i--) {
6086            removeDyingProviderLocked(null, providers.get(i), true);
6087        }
6088
6089        // Remove transient permissions granted from/to this package/user
6090        removeUriPermissionsForPackageLocked(packageName, userId, false);
6091
6092        if (doit) {
6093            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6094                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6095                        packageName, null, userId, doit);
6096            }
6097        }
6098
6099        if (packageName == null || uninstalling) {
6100            // Remove pending intents.  For now we only do this when force
6101            // stopping users, because we have some problems when doing this
6102            // for packages -- app widgets are not currently cleaned up for
6103            // such packages, so they can be left with bad pending intents.
6104            if (mIntentSenderRecords.size() > 0) {
6105                Iterator<WeakReference<PendingIntentRecord>> it
6106                        = mIntentSenderRecords.values().iterator();
6107                while (it.hasNext()) {
6108                    WeakReference<PendingIntentRecord> wpir = it.next();
6109                    if (wpir == null) {
6110                        it.remove();
6111                        continue;
6112                    }
6113                    PendingIntentRecord pir = wpir.get();
6114                    if (pir == null) {
6115                        it.remove();
6116                        continue;
6117                    }
6118                    if (packageName == null) {
6119                        // Stopping user, remove all objects for the user.
6120                        if (pir.key.userId != userId) {
6121                            // Not the same user, skip it.
6122                            continue;
6123                        }
6124                    } else {
6125                        if (UserHandle.getAppId(pir.uid) != appId) {
6126                            // Different app id, skip it.
6127                            continue;
6128                        }
6129                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6130                            // Different user, skip it.
6131                            continue;
6132                        }
6133                        if (!pir.key.packageName.equals(packageName)) {
6134                            // Different package, skip it.
6135                            continue;
6136                        }
6137                    }
6138                    if (!doit) {
6139                        return true;
6140                    }
6141                    didSomething = true;
6142                    it.remove();
6143                    pir.canceled = true;
6144                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6145                        pir.key.activity.pendingResults.remove(pir.ref);
6146                    }
6147                }
6148            }
6149        }
6150
6151        if (doit) {
6152            if (purgeCache && packageName != null) {
6153                AttributeCache ac = AttributeCache.instance();
6154                if (ac != null) {
6155                    ac.removePackage(packageName);
6156                }
6157            }
6158            if (mBooted) {
6159                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6160                mStackSupervisor.scheduleIdleLocked();
6161            }
6162        }
6163
6164        return didSomething;
6165    }
6166
6167    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6168        ProcessRecord old = mProcessNames.remove(name, uid);
6169        if (old != null) {
6170            old.uidRecord.numProcs--;
6171            if (old.uidRecord.numProcs == 0) {
6172                // No more processes using this uid, tell clients it is gone.
6173                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6174                        "No more processes in " + old.uidRecord);
6175                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6176                mActiveUids.remove(uid);
6177                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6178            }
6179            old.uidRecord = null;
6180        }
6181        mIsolatedProcesses.remove(uid);
6182        return old;
6183    }
6184
6185    private final void addProcessNameLocked(ProcessRecord proc) {
6186        // We shouldn't already have a process under this name, but just in case we
6187        // need to clean up whatever may be there now.
6188        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6189        if (old == proc && proc.persistent) {
6190            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6191            Slog.w(TAG, "Re-adding persistent process " + proc);
6192        } else if (old != null) {
6193            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6194        }
6195        UidRecord uidRec = mActiveUids.get(proc.uid);
6196        if (uidRec == null) {
6197            uidRec = new UidRecord(proc.uid);
6198            // This is the first appearance of the uid, report it now!
6199            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6200                    "Creating new process uid: " + uidRec);
6201            mActiveUids.put(proc.uid, uidRec);
6202            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6203            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6204        }
6205        proc.uidRecord = uidRec;
6206        uidRec.numProcs++;
6207        mProcessNames.put(proc.processName, proc.uid, proc);
6208        if (proc.isolated) {
6209            mIsolatedProcesses.put(proc.uid, proc);
6210        }
6211    }
6212
6213    boolean removeProcessLocked(ProcessRecord app,
6214            boolean callerWillRestart, boolean allowRestart, String reason) {
6215        final String name = app.processName;
6216        final int uid = app.uid;
6217        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6218            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6219
6220        ProcessRecord old = mProcessNames.get(name, uid);
6221        if (old != app) {
6222            // This process is no longer active, so nothing to do.
6223            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6224            return false;
6225        }
6226        removeProcessNameLocked(name, uid);
6227        if (mHeavyWeightProcess == app) {
6228            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6229                    mHeavyWeightProcess.userId, 0));
6230            mHeavyWeightProcess = null;
6231        }
6232        boolean needRestart = false;
6233        if (app.pid > 0 && app.pid != MY_PID) {
6234            int pid = app.pid;
6235            synchronized (mPidsSelfLocked) {
6236                mPidsSelfLocked.remove(pid);
6237                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6238            }
6239            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6240            if (app.isolated) {
6241                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6242            }
6243            boolean willRestart = false;
6244            if (app.persistent && !app.isolated) {
6245                if (!callerWillRestart) {
6246                    willRestart = true;
6247                } else {
6248                    needRestart = true;
6249                }
6250            }
6251            app.kill(reason, true);
6252            handleAppDiedLocked(app, willRestart, allowRestart);
6253            if (willRestart) {
6254                removeLruProcessLocked(app);
6255                addAppLocked(app.info, false, null /* ABI override */);
6256            }
6257        } else {
6258            mRemovedProcesses.add(app);
6259        }
6260
6261        return needRestart;
6262    }
6263
6264    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6265        cleanupAppInLaunchingProvidersLocked(app, true);
6266        removeProcessLocked(app, false, true, "timeout publishing content providers");
6267    }
6268
6269    private final void processStartTimedOutLocked(ProcessRecord app) {
6270        final int pid = app.pid;
6271        boolean gone = false;
6272        synchronized (mPidsSelfLocked) {
6273            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6274            if (knownApp != null && knownApp.thread == null) {
6275                mPidsSelfLocked.remove(pid);
6276                gone = true;
6277            }
6278        }
6279
6280        if (gone) {
6281            Slog.w(TAG, "Process " + app + " failed to attach");
6282            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6283                    pid, app.uid, app.processName);
6284            removeProcessNameLocked(app.processName, app.uid);
6285            if (mHeavyWeightProcess == app) {
6286                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6287                        mHeavyWeightProcess.userId, 0));
6288                mHeavyWeightProcess = null;
6289            }
6290            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6291            if (app.isolated) {
6292                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6293            }
6294            // Take care of any launching providers waiting for this process.
6295            cleanupAppInLaunchingProvidersLocked(app, true);
6296            // Take care of any services that are waiting for the process.
6297            mServices.processStartTimedOutLocked(app);
6298            app.kill("start timeout", true);
6299            removeLruProcessLocked(app);
6300            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6301                Slog.w(TAG, "Unattached app died before backup, skipping");
6302                try {
6303                    IBackupManager bm = IBackupManager.Stub.asInterface(
6304                            ServiceManager.getService(Context.BACKUP_SERVICE));
6305                    bm.agentDisconnected(app.info.packageName);
6306                } catch (RemoteException e) {
6307                    // Can't happen; the backup manager is local
6308                }
6309            }
6310            if (isPendingBroadcastProcessLocked(pid)) {
6311                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6312                skipPendingBroadcastLocked(pid);
6313            }
6314        } else {
6315            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6316        }
6317    }
6318
6319    private final boolean attachApplicationLocked(IApplicationThread thread,
6320            int pid) {
6321
6322        // Find the application record that is being attached...  either via
6323        // the pid if we are running in multiple processes, or just pull the
6324        // next app record if we are emulating process with anonymous threads.
6325        ProcessRecord app;
6326        if (pid != MY_PID && pid >= 0) {
6327            synchronized (mPidsSelfLocked) {
6328                app = mPidsSelfLocked.get(pid);
6329            }
6330        } else {
6331            app = null;
6332        }
6333
6334        if (app == null) {
6335            Slog.w(TAG, "No pending application record for pid " + pid
6336                    + " (IApplicationThread " + thread + "); dropping process");
6337            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6338            if (pid > 0 && pid != MY_PID) {
6339                Process.killProcessQuiet(pid);
6340                //TODO: killProcessGroup(app.info.uid, pid);
6341            } else {
6342                try {
6343                    thread.scheduleExit();
6344                } catch (Exception e) {
6345                    // Ignore exceptions.
6346                }
6347            }
6348            return false;
6349        }
6350
6351        // If this application record is still attached to a previous
6352        // process, clean it up now.
6353        if (app.thread != null) {
6354            handleAppDiedLocked(app, true, true);
6355        }
6356
6357        // Tell the process all about itself.
6358
6359        if (DEBUG_ALL) Slog.v(
6360                TAG, "Binding process pid " + pid + " to record " + app);
6361
6362        final String processName = app.processName;
6363        try {
6364            AppDeathRecipient adr = new AppDeathRecipient(
6365                    app, pid, thread);
6366            thread.asBinder().linkToDeath(adr, 0);
6367            app.deathRecipient = adr;
6368        } catch (RemoteException e) {
6369            app.resetPackageList(mProcessStats);
6370            startProcessLocked(app, "link fail", processName);
6371            return false;
6372        }
6373
6374        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6375
6376        app.makeActive(thread, mProcessStats);
6377        app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6378        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6379        app.forcingToForeground = null;
6380        updateProcessForegroundLocked(app, false, false);
6381        app.hasShownUi = false;
6382        app.debugging = false;
6383        app.cached = false;
6384        app.killedByAm = false;
6385
6386        // We carefully use the same state that PackageManager uses for
6387        // filtering, since we use this flag to decide if we need to install
6388        // providers when user is unlocked later
6389        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6390
6391        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6392
6393        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6394        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6395
6396        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6397            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6398            msg.obj = app;
6399            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6400        }
6401
6402        if (!normalMode) {
6403            Slog.i(TAG, "Launching preboot mode app: " + app);
6404        }
6405
6406        if (DEBUG_ALL) Slog.v(
6407            TAG, "New app record " + app
6408            + " thread=" + thread.asBinder() + " pid=" + pid);
6409        try {
6410            int testMode = IApplicationThread.DEBUG_OFF;
6411            if (mDebugApp != null && mDebugApp.equals(processName)) {
6412                testMode = mWaitForDebugger
6413                    ? IApplicationThread.DEBUG_WAIT
6414                    : IApplicationThread.DEBUG_ON;
6415                app.debugging = true;
6416                if (mDebugTransient) {
6417                    mDebugApp = mOrigDebugApp;
6418                    mWaitForDebugger = mOrigWaitForDebugger;
6419                }
6420            }
6421            String profileFile = app.instrumentationProfileFile;
6422            ParcelFileDescriptor profileFd = null;
6423            int samplingInterval = 0;
6424            boolean profileAutoStop = false;
6425            if (mProfileApp != null && mProfileApp.equals(processName)) {
6426                mProfileProc = app;
6427                profileFile = mProfileFile;
6428                profileFd = mProfileFd;
6429                samplingInterval = mSamplingInterval;
6430                profileAutoStop = mAutoStopProfiler;
6431            }
6432            boolean enableTrackAllocation = false;
6433            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6434                enableTrackAllocation = true;
6435                mTrackAllocationApp = null;
6436            }
6437
6438            // If the app is being launched for restore or full backup, set it up specially
6439            boolean isRestrictedBackupMode = false;
6440            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6441                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6442                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6443                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6444                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6445            }
6446
6447            if (app.instrumentationClass != null) {
6448                notifyPackageUse(app.instrumentationClass.getPackageName(),
6449                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6450            }
6451            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6452                    + processName + " with config " + mConfiguration);
6453            ApplicationInfo appInfo = app.instrumentationInfo != null
6454                    ? app.instrumentationInfo : app.info;
6455            app.compat = compatibilityInfoForPackageLocked(appInfo);
6456            if (profileFd != null) {
6457                profileFd = profileFd.dup();
6458            }
6459            ProfilerInfo profilerInfo = profileFile == null ? null
6460                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6461            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6462                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6463                    app.instrumentationUiAutomationConnection, testMode,
6464                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6465                    isRestrictedBackupMode || !normalMode, app.persistent,
6466                    new Configuration(mConfiguration), app.compat,
6467                    getCommonServicesLocked(app.isolated),
6468                    mCoreSettingsObserver.getCoreSettingsLocked());
6469            updateLruProcessLocked(app, false, null);
6470            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6471        } catch (Exception e) {
6472            // todo: Yikes!  What should we do?  For now we will try to
6473            // start another process, but that could easily get us in
6474            // an infinite loop of restarting processes...
6475            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6476
6477            app.resetPackageList(mProcessStats);
6478            app.unlinkDeathRecipient();
6479            startProcessLocked(app, "bind fail", processName);
6480            return false;
6481        }
6482
6483        // Remove this record from the list of starting applications.
6484        mPersistentStartingProcesses.remove(app);
6485        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6486                "Attach application locked removing on hold: " + app);
6487        mProcessesOnHold.remove(app);
6488
6489        boolean badApp = false;
6490        boolean didSomething = false;
6491
6492        // See if the top visible activity is waiting to run in this process...
6493        if (normalMode) {
6494            try {
6495                if (mStackSupervisor.attachApplicationLocked(app)) {
6496                    didSomething = true;
6497                }
6498            } catch (Exception e) {
6499                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6500                badApp = true;
6501            }
6502        }
6503
6504        // Find any services that should be running in this process...
6505        if (!badApp) {
6506            try {
6507                didSomething |= mServices.attachApplicationLocked(app, processName);
6508            } catch (Exception e) {
6509                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6510                badApp = true;
6511            }
6512        }
6513
6514        // Check if a next-broadcast receiver is in this process...
6515        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6516            try {
6517                didSomething |= sendPendingBroadcastsLocked(app);
6518            } catch (Exception e) {
6519                // If the app died trying to launch the receiver we declare it 'bad'
6520                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6521                badApp = true;
6522            }
6523        }
6524
6525        // Check whether the next backup agent is in this process...
6526        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6527            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6528                    "New app is backup target, launching agent for " + app);
6529            notifyPackageUse(mBackupTarget.appInfo.packageName,
6530                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6531            try {
6532                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6533                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6534                        mBackupTarget.backupMode);
6535            } catch (Exception e) {
6536                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6537                badApp = true;
6538            }
6539        }
6540
6541        if (badApp) {
6542            app.kill("error during init", true);
6543            handleAppDiedLocked(app, false, true);
6544            return false;
6545        }
6546
6547        if (!didSomething) {
6548            updateOomAdjLocked();
6549        }
6550
6551        return true;
6552    }
6553
6554    @Override
6555    public final void attachApplication(IApplicationThread thread) {
6556        synchronized (this) {
6557            int callingPid = Binder.getCallingPid();
6558            final long origId = Binder.clearCallingIdentity();
6559            attachApplicationLocked(thread, callingPid);
6560            Binder.restoreCallingIdentity(origId);
6561        }
6562    }
6563
6564    @Override
6565    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6566        final long origId = Binder.clearCallingIdentity();
6567        synchronized (this) {
6568            ActivityStack stack = ActivityRecord.getStackLocked(token);
6569            if (stack != null) {
6570                ActivityRecord r =
6571                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6572                if (stopProfiling) {
6573                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6574                        try {
6575                            mProfileFd.close();
6576                        } catch (IOException e) {
6577                        }
6578                        clearProfilerLocked();
6579                    }
6580                }
6581            }
6582        }
6583        Binder.restoreCallingIdentity(origId);
6584    }
6585
6586    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6587        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6588                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6589    }
6590
6591    void enableScreenAfterBoot() {
6592        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6593                SystemClock.uptimeMillis());
6594        mWindowManager.enableScreenAfterBoot();
6595
6596        synchronized (this) {
6597            updateEventDispatchingLocked();
6598        }
6599    }
6600
6601    @Override
6602    public void showBootMessage(final CharSequence msg, final boolean always) {
6603        if (Binder.getCallingUid() != Process.myUid()) {
6604            // These days only the core system can call this, so apps can't get in
6605            // the way of what we show about running them.
6606        }
6607        mWindowManager.showBootMessage(msg, always);
6608    }
6609
6610    @Override
6611    public void keyguardWaitingForActivityDrawn() {
6612        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6613        final long token = Binder.clearCallingIdentity();
6614        try {
6615            synchronized (this) {
6616                if (DEBUG_LOCKSCREEN) logLockScreen("");
6617                mWindowManager.keyguardWaitingForActivityDrawn();
6618                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6619                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6620                    updateSleepIfNeededLocked();
6621                }
6622            }
6623        } finally {
6624            Binder.restoreCallingIdentity(token);
6625        }
6626    }
6627
6628    @Override
6629    public void keyguardGoingAway(int flags) {
6630        enforceNotIsolatedCaller("keyguardGoingAway");
6631        final long token = Binder.clearCallingIdentity();
6632        try {
6633            synchronized (this) {
6634                if (DEBUG_LOCKSCREEN) logLockScreen("");
6635                mWindowManager.keyguardGoingAway(flags);
6636                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6637                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6638                    updateSleepIfNeededLocked();
6639
6640                    // Some stack visibility might change (e.g. docked stack)
6641                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6642                    applyVrModeIfNeededLocked(mFocusedActivity, true);
6643                }
6644            }
6645        } finally {
6646            Binder.restoreCallingIdentity(token);
6647        }
6648    }
6649
6650    final void finishBooting() {
6651        synchronized (this) {
6652            if (!mBootAnimationComplete) {
6653                mCallFinishBooting = true;
6654                return;
6655            }
6656            mCallFinishBooting = false;
6657        }
6658
6659        ArraySet<String> completedIsas = new ArraySet<String>();
6660        for (String abi : Build.SUPPORTED_ABIS) {
6661            Process.establishZygoteConnectionForAbi(abi);
6662            final String instructionSet = VMRuntime.getInstructionSet(abi);
6663            if (!completedIsas.contains(instructionSet)) {
6664                try {
6665                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6666                } catch (InstallerException e) {
6667                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6668                            e.getMessage() +")");
6669                }
6670                completedIsas.add(instructionSet);
6671            }
6672        }
6673
6674        IntentFilter pkgFilter = new IntentFilter();
6675        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6676        pkgFilter.addDataScheme("package");
6677        mContext.registerReceiver(new BroadcastReceiver() {
6678            @Override
6679            public void onReceive(Context context, Intent intent) {
6680                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6681                if (pkgs != null) {
6682                    for (String pkg : pkgs) {
6683                        synchronized (ActivityManagerService.this) {
6684                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6685                                    0, "query restart")) {
6686                                setResultCode(Activity.RESULT_OK);
6687                                return;
6688                            }
6689                        }
6690                    }
6691                }
6692            }
6693        }, pkgFilter);
6694
6695        IntentFilter dumpheapFilter = new IntentFilter();
6696        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6697        mContext.registerReceiver(new BroadcastReceiver() {
6698            @Override
6699            public void onReceive(Context context, Intent intent) {
6700                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6701                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6702                } else {
6703                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6704                }
6705            }
6706        }, dumpheapFilter);
6707
6708        // Let system services know.
6709        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6710
6711        synchronized (this) {
6712            // Ensure that any processes we had put on hold are now started
6713            // up.
6714            final int NP = mProcessesOnHold.size();
6715            if (NP > 0) {
6716                ArrayList<ProcessRecord> procs =
6717                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6718                for (int ip=0; ip<NP; ip++) {
6719                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6720                            + procs.get(ip));
6721                    startProcessLocked(procs.get(ip), "on-hold", null);
6722                }
6723            }
6724
6725            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6726                // Start looking for apps that are abusing wake locks.
6727                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6728                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6729                // Tell anyone interested that we are done booting!
6730                SystemProperties.set("sys.boot_completed", "1");
6731
6732                // And trigger dev.bootcomplete if we are not showing encryption progress
6733                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6734                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6735                    SystemProperties.set("dev.bootcomplete", "1");
6736                }
6737                mUserController.sendBootCompletedLocked(
6738                        new IIntentReceiver.Stub() {
6739                            @Override
6740                            public void performReceive(Intent intent, int resultCode,
6741                                    String data, Bundle extras, boolean ordered,
6742                                    boolean sticky, int sendingUser) {
6743                                synchronized (ActivityManagerService.this) {
6744                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6745                                            true, false);
6746                                }
6747                            }
6748                        });
6749                scheduleStartProfilesLocked();
6750            }
6751        }
6752    }
6753
6754    @Override
6755    public void bootAnimationComplete() {
6756        final boolean callFinishBooting;
6757        synchronized (this) {
6758            callFinishBooting = mCallFinishBooting;
6759            mBootAnimationComplete = true;
6760        }
6761        if (callFinishBooting) {
6762            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6763            finishBooting();
6764            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6765        }
6766    }
6767
6768    final void ensureBootCompleted() {
6769        boolean booting;
6770        boolean enableScreen;
6771        synchronized (this) {
6772            booting = mBooting;
6773            mBooting = false;
6774            enableScreen = !mBooted;
6775            mBooted = true;
6776        }
6777
6778        if (booting) {
6779            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6780            finishBooting();
6781            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6782        }
6783
6784        if (enableScreen) {
6785            enableScreenAfterBoot();
6786        }
6787    }
6788
6789    @Override
6790    public final void activityResumed(IBinder token) {
6791        final long origId = Binder.clearCallingIdentity();
6792        synchronized(this) {
6793            ActivityStack stack = ActivityRecord.getStackLocked(token);
6794            if (stack != null) {
6795                stack.activityResumedLocked(token);
6796            }
6797        }
6798        Binder.restoreCallingIdentity(origId);
6799    }
6800
6801    @Override
6802    public final void activityPaused(IBinder token) {
6803        final long origId = Binder.clearCallingIdentity();
6804        synchronized(this) {
6805            ActivityStack stack = ActivityRecord.getStackLocked(token);
6806            if (stack != null) {
6807                stack.activityPausedLocked(token, false);
6808            }
6809        }
6810        Binder.restoreCallingIdentity(origId);
6811    }
6812
6813    @Override
6814    public final void activityStopped(IBinder token, Bundle icicle,
6815            PersistableBundle persistentState, CharSequence description) {
6816        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6817
6818        // Refuse possible leaked file descriptors
6819        if (icicle != null && icicle.hasFileDescriptors()) {
6820            throw new IllegalArgumentException("File descriptors passed in Bundle");
6821        }
6822
6823        final long origId = Binder.clearCallingIdentity();
6824
6825        synchronized (this) {
6826            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6827            if (r != null) {
6828                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6829            }
6830        }
6831
6832        trimApplications();
6833
6834        Binder.restoreCallingIdentity(origId);
6835    }
6836
6837    @Override
6838    public final void activityDestroyed(IBinder token) {
6839        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6840        synchronized (this) {
6841            ActivityStack stack = ActivityRecord.getStackLocked(token);
6842            if (stack != null) {
6843                stack.activityDestroyedLocked(token, "activityDestroyed");
6844            }
6845        }
6846    }
6847
6848    @Override
6849    public final void activityRelaunched(IBinder token) {
6850        final long origId = Binder.clearCallingIdentity();
6851        synchronized (this) {
6852            mStackSupervisor.activityRelaunchedLocked(token);
6853        }
6854        Binder.restoreCallingIdentity(origId);
6855    }
6856
6857    @Override
6858    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6859            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6860        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6861                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6862        synchronized (this) {
6863            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6864            if (record == null) {
6865                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6866                        + "found for: " + token);
6867            }
6868            record.setSizeConfigurations(horizontalSizeConfiguration,
6869                    verticalSizeConfigurations, smallestSizeConfigurations);
6870        }
6871    }
6872
6873    @Override
6874    public final void backgroundResourcesReleased(IBinder token) {
6875        final long origId = Binder.clearCallingIdentity();
6876        try {
6877            synchronized (this) {
6878                ActivityStack stack = ActivityRecord.getStackLocked(token);
6879                if (stack != null) {
6880                    stack.backgroundResourcesReleased();
6881                }
6882            }
6883        } finally {
6884            Binder.restoreCallingIdentity(origId);
6885        }
6886    }
6887
6888    @Override
6889    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6890        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6891    }
6892
6893    @Override
6894    public final void notifyEnterAnimationComplete(IBinder token) {
6895        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6896    }
6897
6898    @Override
6899    public String getCallingPackage(IBinder token) {
6900        synchronized (this) {
6901            ActivityRecord r = getCallingRecordLocked(token);
6902            return r != null ? r.info.packageName : null;
6903        }
6904    }
6905
6906    @Override
6907    public ComponentName getCallingActivity(IBinder token) {
6908        synchronized (this) {
6909            ActivityRecord r = getCallingRecordLocked(token);
6910            return r != null ? r.intent.getComponent() : null;
6911        }
6912    }
6913
6914    private ActivityRecord getCallingRecordLocked(IBinder token) {
6915        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6916        if (r == null) {
6917            return null;
6918        }
6919        return r.resultTo;
6920    }
6921
6922    @Override
6923    public ComponentName getActivityClassForToken(IBinder token) {
6924        synchronized(this) {
6925            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6926            if (r == null) {
6927                return null;
6928            }
6929            return r.intent.getComponent();
6930        }
6931    }
6932
6933    @Override
6934    public String getPackageForToken(IBinder token) {
6935        synchronized(this) {
6936            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6937            if (r == null) {
6938                return null;
6939            }
6940            return r.packageName;
6941        }
6942    }
6943
6944    @Override
6945    public boolean isRootVoiceInteraction(IBinder token) {
6946        synchronized(this) {
6947            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6948            if (r == null) {
6949                return false;
6950            }
6951            return r.rootVoiceInteraction;
6952        }
6953    }
6954
6955    @Override
6956    public IIntentSender getIntentSender(int type,
6957            String packageName, IBinder token, String resultWho,
6958            int requestCode, Intent[] intents, String[] resolvedTypes,
6959            int flags, Bundle bOptions, int userId) {
6960        enforceNotIsolatedCaller("getIntentSender");
6961        // Refuse possible leaked file descriptors
6962        if (intents != null) {
6963            if (intents.length < 1) {
6964                throw new IllegalArgumentException("Intents array length must be >= 1");
6965            }
6966            for (int i=0; i<intents.length; i++) {
6967                Intent intent = intents[i];
6968                if (intent != null) {
6969                    if (intent.hasFileDescriptors()) {
6970                        throw new IllegalArgumentException("File descriptors passed in Intent");
6971                    }
6972                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6973                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6974                        throw new IllegalArgumentException(
6975                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6976                    }
6977                    intents[i] = new Intent(intent);
6978                }
6979            }
6980            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6981                throw new IllegalArgumentException(
6982                        "Intent array length does not match resolvedTypes length");
6983            }
6984        }
6985        if (bOptions != null) {
6986            if (bOptions.hasFileDescriptors()) {
6987                throw new IllegalArgumentException("File descriptors passed in options");
6988            }
6989        }
6990
6991        synchronized(this) {
6992            int callingUid = Binder.getCallingUid();
6993            int origUserId = userId;
6994            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6995                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6996                    ALLOW_NON_FULL, "getIntentSender", null);
6997            if (origUserId == UserHandle.USER_CURRENT) {
6998                // We don't want to evaluate this until the pending intent is
6999                // actually executed.  However, we do want to always do the
7000                // security checking for it above.
7001                userId = UserHandle.USER_CURRENT;
7002            }
7003            try {
7004                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7005                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7006                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7007                    if (!UserHandle.isSameApp(callingUid, uid)) {
7008                        String msg = "Permission Denial: getIntentSender() from pid="
7009                            + Binder.getCallingPid()
7010                            + ", uid=" + Binder.getCallingUid()
7011                            + ", (need uid=" + uid + ")"
7012                            + " is not allowed to send as package " + packageName;
7013                        Slog.w(TAG, msg);
7014                        throw new SecurityException(msg);
7015                    }
7016                }
7017
7018                return getIntentSenderLocked(type, packageName, callingUid, userId,
7019                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7020
7021            } catch (RemoteException e) {
7022                throw new SecurityException(e);
7023            }
7024        }
7025    }
7026
7027    IIntentSender getIntentSenderLocked(int type, String packageName,
7028            int callingUid, int userId, IBinder token, String resultWho,
7029            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7030            Bundle bOptions) {
7031        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7032        ActivityRecord activity = null;
7033        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7034            activity = ActivityRecord.isInStackLocked(token);
7035            if (activity == null) {
7036                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7037                return null;
7038            }
7039            if (activity.finishing) {
7040                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7041                return null;
7042            }
7043        }
7044
7045        // We're going to be splicing together extras before sending, so we're
7046        // okay poking into any contained extras.
7047        if (intents != null) {
7048            for (int i = 0; i < intents.length; i++) {
7049                intents[i].setDefusable(true);
7050            }
7051        }
7052        Bundle.setDefusable(bOptions, true);
7053
7054        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7055        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7056        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7057        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7058                |PendingIntent.FLAG_UPDATE_CURRENT);
7059
7060        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7061                type, packageName, activity, resultWho,
7062                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7063        WeakReference<PendingIntentRecord> ref;
7064        ref = mIntentSenderRecords.get(key);
7065        PendingIntentRecord rec = ref != null ? ref.get() : null;
7066        if (rec != null) {
7067            if (!cancelCurrent) {
7068                if (updateCurrent) {
7069                    if (rec.key.requestIntent != null) {
7070                        rec.key.requestIntent.replaceExtras(intents != null ?
7071                                intents[intents.length - 1] : null);
7072                    }
7073                    if (intents != null) {
7074                        intents[intents.length-1] = rec.key.requestIntent;
7075                        rec.key.allIntents = intents;
7076                        rec.key.allResolvedTypes = resolvedTypes;
7077                    } else {
7078                        rec.key.allIntents = null;
7079                        rec.key.allResolvedTypes = null;
7080                    }
7081                }
7082                return rec;
7083            }
7084            rec.canceled = true;
7085            mIntentSenderRecords.remove(key);
7086        }
7087        if (noCreate) {
7088            return rec;
7089        }
7090        rec = new PendingIntentRecord(this, key, callingUid);
7091        mIntentSenderRecords.put(key, rec.ref);
7092        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7093            if (activity.pendingResults == null) {
7094                activity.pendingResults
7095                        = new HashSet<WeakReference<PendingIntentRecord>>();
7096            }
7097            activity.pendingResults.add(rec.ref);
7098        }
7099        return rec;
7100    }
7101
7102    @Override
7103    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7104            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7105        if (target instanceof PendingIntentRecord) {
7106            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7107                    finishedReceiver, requiredPermission, options);
7108        } else {
7109            if (intent == null) {
7110                // Weird case: someone has given us their own custom IIntentSender, and now
7111                // they have someone else trying to send to it but of course this isn't
7112                // really a PendingIntent, so there is no base Intent, and the caller isn't
7113                // supplying an Intent... but we never want to dispatch a null Intent to
7114                // a receiver, so um...  let's make something up.
7115                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7116                intent = new Intent(Intent.ACTION_MAIN);
7117            }
7118            try {
7119                target.send(code, intent, resolvedType, null, requiredPermission, options);
7120            } catch (RemoteException e) {
7121            }
7122            // Platform code can rely on getting a result back when the send is done, but if
7123            // this intent sender is from outside of the system we can't rely on it doing that.
7124            // So instead we don't give it the result receiver, and instead just directly
7125            // report the finish immediately.
7126            if (finishedReceiver != null) {
7127                try {
7128                    finishedReceiver.performReceive(intent, 0,
7129                            null, null, false, false, UserHandle.getCallingUserId());
7130                } catch (RemoteException e) {
7131                }
7132            }
7133            return 0;
7134        }
7135    }
7136
7137    @Override
7138    public void cancelIntentSender(IIntentSender sender) {
7139        if (!(sender instanceof PendingIntentRecord)) {
7140            return;
7141        }
7142        synchronized(this) {
7143            PendingIntentRecord rec = (PendingIntentRecord)sender;
7144            try {
7145                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7146                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7147                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7148                    String msg = "Permission Denial: cancelIntentSender() from pid="
7149                        + Binder.getCallingPid()
7150                        + ", uid=" + Binder.getCallingUid()
7151                        + " is not allowed to cancel packges "
7152                        + rec.key.packageName;
7153                    Slog.w(TAG, msg);
7154                    throw new SecurityException(msg);
7155                }
7156            } catch (RemoteException e) {
7157                throw new SecurityException(e);
7158            }
7159            cancelIntentSenderLocked(rec, true);
7160        }
7161    }
7162
7163    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7164        rec.canceled = true;
7165        mIntentSenderRecords.remove(rec.key);
7166        if (cleanActivity && rec.key.activity != null) {
7167            rec.key.activity.pendingResults.remove(rec.ref);
7168        }
7169    }
7170
7171    @Override
7172    public String getPackageForIntentSender(IIntentSender pendingResult) {
7173        if (!(pendingResult instanceof PendingIntentRecord)) {
7174            return null;
7175        }
7176        try {
7177            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7178            return res.key.packageName;
7179        } catch (ClassCastException e) {
7180        }
7181        return null;
7182    }
7183
7184    @Override
7185    public int getUidForIntentSender(IIntentSender sender) {
7186        if (sender instanceof PendingIntentRecord) {
7187            try {
7188                PendingIntentRecord res = (PendingIntentRecord)sender;
7189                return res.uid;
7190            } catch (ClassCastException e) {
7191            }
7192        }
7193        return -1;
7194    }
7195
7196    @Override
7197    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7198        if (!(pendingResult instanceof PendingIntentRecord)) {
7199            return false;
7200        }
7201        try {
7202            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7203            if (res.key.allIntents == null) {
7204                return false;
7205            }
7206            for (int i=0; i<res.key.allIntents.length; i++) {
7207                Intent intent = res.key.allIntents[i];
7208                if (intent.getPackage() != null && intent.getComponent() != null) {
7209                    return false;
7210                }
7211            }
7212            return true;
7213        } catch (ClassCastException e) {
7214        }
7215        return false;
7216    }
7217
7218    @Override
7219    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7220        if (!(pendingResult instanceof PendingIntentRecord)) {
7221            return false;
7222        }
7223        try {
7224            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7225            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7226                return true;
7227            }
7228            return false;
7229        } catch (ClassCastException e) {
7230        }
7231        return false;
7232    }
7233
7234    @Override
7235    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7236        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7237                "getIntentForIntentSender()");
7238        if (!(pendingResult instanceof PendingIntentRecord)) {
7239            return null;
7240        }
7241        try {
7242            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7243            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7244        } catch (ClassCastException e) {
7245        }
7246        return null;
7247    }
7248
7249    @Override
7250    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7251        if (!(pendingResult instanceof PendingIntentRecord)) {
7252            return null;
7253        }
7254        try {
7255            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7256            synchronized (this) {
7257                return getTagForIntentSenderLocked(res, prefix);
7258            }
7259        } catch (ClassCastException e) {
7260        }
7261        return null;
7262    }
7263
7264    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7265        final Intent intent = res.key.requestIntent;
7266        if (intent != null) {
7267            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7268                    || res.lastTagPrefix.equals(prefix))) {
7269                return res.lastTag;
7270            }
7271            res.lastTagPrefix = prefix;
7272            final StringBuilder sb = new StringBuilder(128);
7273            if (prefix != null) {
7274                sb.append(prefix);
7275            }
7276            if (intent.getAction() != null) {
7277                sb.append(intent.getAction());
7278            } else if (intent.getComponent() != null) {
7279                intent.getComponent().appendShortString(sb);
7280            } else {
7281                sb.append("?");
7282            }
7283            return res.lastTag = sb.toString();
7284        }
7285        return null;
7286    }
7287
7288    @Override
7289    public void setProcessLimit(int max) {
7290        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7291                "setProcessLimit()");
7292        synchronized (this) {
7293            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7294            mProcessLimitOverride = max;
7295        }
7296        trimApplications();
7297    }
7298
7299    @Override
7300    public int getProcessLimit() {
7301        synchronized (this) {
7302            return mProcessLimitOverride;
7303        }
7304    }
7305
7306    void foregroundTokenDied(ForegroundToken token) {
7307        synchronized (ActivityManagerService.this) {
7308            synchronized (mPidsSelfLocked) {
7309                ForegroundToken cur
7310                    = mForegroundProcesses.get(token.pid);
7311                if (cur != token) {
7312                    return;
7313                }
7314                mForegroundProcesses.remove(token.pid);
7315                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7316                if (pr == null) {
7317                    return;
7318                }
7319                pr.forcingToForeground = null;
7320                updateProcessForegroundLocked(pr, false, false);
7321            }
7322            updateOomAdjLocked();
7323        }
7324    }
7325
7326    @Override
7327    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7328        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7329                "setProcessForeground()");
7330        synchronized(this) {
7331            boolean changed = false;
7332
7333            synchronized (mPidsSelfLocked) {
7334                ProcessRecord pr = mPidsSelfLocked.get(pid);
7335                if (pr == null && isForeground) {
7336                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7337                    return;
7338                }
7339                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7340                if (oldToken != null) {
7341                    oldToken.token.unlinkToDeath(oldToken, 0);
7342                    mForegroundProcesses.remove(pid);
7343                    if (pr != null) {
7344                        pr.forcingToForeground = null;
7345                    }
7346                    changed = true;
7347                }
7348                if (isForeground && token != null) {
7349                    ForegroundToken newToken = new ForegroundToken() {
7350                        @Override
7351                        public void binderDied() {
7352                            foregroundTokenDied(this);
7353                        }
7354                    };
7355                    newToken.pid = pid;
7356                    newToken.token = token;
7357                    try {
7358                        token.linkToDeath(newToken, 0);
7359                        mForegroundProcesses.put(pid, newToken);
7360                        pr.forcingToForeground = token;
7361                        changed = true;
7362                    } catch (RemoteException e) {
7363                        // If the process died while doing this, we will later
7364                        // do the cleanup with the process death link.
7365                    }
7366                }
7367            }
7368
7369            if (changed) {
7370                updateOomAdjLocked();
7371            }
7372        }
7373    }
7374
7375    @Override
7376    public boolean isAppForeground(int uid) throws RemoteException {
7377        synchronized (this) {
7378            UidRecord uidRec = mActiveUids.get(uid);
7379            if (uidRec == null || uidRec.idle) {
7380                return false;
7381            }
7382            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7383        }
7384    }
7385
7386    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7387    // be guarded by permission checking.
7388    int getUidState(int uid) {
7389        synchronized (this) {
7390            UidRecord uidRec = mActiveUids.get(uid);
7391            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7392        }
7393    }
7394
7395    @Override
7396    public boolean isInMultiWindowMode(IBinder token) {
7397        final long origId = Binder.clearCallingIdentity();
7398        try {
7399            synchronized(this) {
7400                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7401                if (r == null) {
7402                    return false;
7403                }
7404                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7405                return !r.task.mFullscreen;
7406            }
7407        } finally {
7408            Binder.restoreCallingIdentity(origId);
7409        }
7410    }
7411
7412    @Override
7413    public boolean isInPictureInPictureMode(IBinder token) {
7414        final long origId = Binder.clearCallingIdentity();
7415        try {
7416            synchronized(this) {
7417                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7418                if (stack == null) {
7419                    return false;
7420                }
7421                return stack.mStackId == PINNED_STACK_ID;
7422            }
7423        } finally {
7424            Binder.restoreCallingIdentity(origId);
7425        }
7426    }
7427
7428    @Override
7429    public void enterPictureInPictureMode(IBinder token) {
7430        final long origId = Binder.clearCallingIdentity();
7431        try {
7432            synchronized(this) {
7433                if (!mSupportsPictureInPicture) {
7434                    throw new IllegalStateException("enterPictureInPictureMode: "
7435                            + "Device doesn't support picture-in-picture mode.");
7436                }
7437
7438                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7439
7440                if (r == null) {
7441                    throw new IllegalStateException("enterPictureInPictureMode: "
7442                            + "Can't find activity for token=" + token);
7443                }
7444
7445                if (!r.supportsPictureInPicture()) {
7446                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7447                            + "Picture-In-Picture not supported for r=" + r);
7448                }
7449
7450                // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7451                // current bounds.
7452                final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7453                final Rect bounds = (pinnedStack != null)
7454                        ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7455
7456                mStackSupervisor.moveActivityToPinnedStackLocked(
7457                        r, "enterPictureInPictureMode", bounds);
7458            }
7459        } finally {
7460            Binder.restoreCallingIdentity(origId);
7461        }
7462    }
7463
7464    // =========================================================
7465    // PROCESS INFO
7466    // =========================================================
7467
7468    static class ProcessInfoService extends IProcessInfoService.Stub {
7469        final ActivityManagerService mActivityManagerService;
7470        ProcessInfoService(ActivityManagerService activityManagerService) {
7471            mActivityManagerService = activityManagerService;
7472        }
7473
7474        @Override
7475        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7476            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7477                    /*in*/ pids, /*out*/ states, null);
7478        }
7479
7480        @Override
7481        public void getProcessStatesAndOomScoresFromPids(
7482                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7483            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7484                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7485        }
7486    }
7487
7488    /**
7489     * For each PID in the given input array, write the current process state
7490     * for that process into the states array, or -1 to indicate that no
7491     * process with the given PID exists. If scores array is provided, write
7492     * the oom score for the process into the scores array, with INVALID_ADJ
7493     * indicating the PID doesn't exist.
7494     */
7495    public void getProcessStatesAndOomScoresForPIDs(
7496            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7497        if (scores != null) {
7498            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7499                    "getProcessStatesAndOomScoresForPIDs()");
7500        }
7501
7502        if (pids == null) {
7503            throw new NullPointerException("pids");
7504        } else if (states == null) {
7505            throw new NullPointerException("states");
7506        } else if (pids.length != states.length) {
7507            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7508        } else if (scores != null && pids.length != scores.length) {
7509            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7510        }
7511
7512        synchronized (mPidsSelfLocked) {
7513            for (int i = 0; i < pids.length; i++) {
7514                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7515                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7516                        pr.curProcState;
7517                if (scores != null) {
7518                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7519                }
7520            }
7521        }
7522    }
7523
7524    // =========================================================
7525    // PERMISSIONS
7526    // =========================================================
7527
7528    static class PermissionController extends IPermissionController.Stub {
7529        ActivityManagerService mActivityManagerService;
7530        PermissionController(ActivityManagerService activityManagerService) {
7531            mActivityManagerService = activityManagerService;
7532        }
7533
7534        @Override
7535        public boolean checkPermission(String permission, int pid, int uid) {
7536            return mActivityManagerService.checkPermission(permission, pid,
7537                    uid) == PackageManager.PERMISSION_GRANTED;
7538        }
7539
7540        @Override
7541        public String[] getPackagesForUid(int uid) {
7542            return mActivityManagerService.mContext.getPackageManager()
7543                    .getPackagesForUid(uid);
7544        }
7545
7546        @Override
7547        public boolean isRuntimePermission(String permission) {
7548            try {
7549                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7550                        .getPermissionInfo(permission, 0);
7551                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7552            } catch (NameNotFoundException nnfe) {
7553                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7554            }
7555            return false;
7556        }
7557    }
7558
7559    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7560        @Override
7561        public int checkComponentPermission(String permission, int pid, int uid,
7562                int owningUid, boolean exported) {
7563            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7564                    owningUid, exported);
7565        }
7566
7567        @Override
7568        public Object getAMSLock() {
7569            return ActivityManagerService.this;
7570        }
7571    }
7572
7573    /**
7574     * This can be called with or without the global lock held.
7575     */
7576    int checkComponentPermission(String permission, int pid, int uid,
7577            int owningUid, boolean exported) {
7578        if (pid == MY_PID) {
7579            return PackageManager.PERMISSION_GRANTED;
7580        }
7581        return ActivityManager.checkComponentPermission(permission, uid,
7582                owningUid, exported);
7583    }
7584
7585    /**
7586     * As the only public entry point for permissions checking, this method
7587     * can enforce the semantic that requesting a check on a null global
7588     * permission is automatically denied.  (Internally a null permission
7589     * string is used when calling {@link #checkComponentPermission} in cases
7590     * when only uid-based security is needed.)
7591     *
7592     * This can be called with or without the global lock held.
7593     */
7594    @Override
7595    public int checkPermission(String permission, int pid, int uid) {
7596        if (permission == null) {
7597            return PackageManager.PERMISSION_DENIED;
7598        }
7599        return checkComponentPermission(permission, pid, uid, -1, true);
7600    }
7601
7602    @Override
7603    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7604        if (permission == null) {
7605            return PackageManager.PERMISSION_DENIED;
7606        }
7607
7608        // We might be performing an operation on behalf of an indirect binder
7609        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7610        // client identity accordingly before proceeding.
7611        Identity tlsIdentity = sCallerIdentity.get();
7612        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7613            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7614                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7615            uid = tlsIdentity.uid;
7616            pid = tlsIdentity.pid;
7617        }
7618
7619        return checkComponentPermission(permission, pid, uid, -1, true);
7620    }
7621
7622    /**
7623     * Binder IPC calls go through the public entry point.
7624     * This can be called with or without the global lock held.
7625     */
7626    int checkCallingPermission(String permission) {
7627        return checkPermission(permission,
7628                Binder.getCallingPid(),
7629                UserHandle.getAppId(Binder.getCallingUid()));
7630    }
7631
7632    /**
7633     * This can be called with or without the global lock held.
7634     */
7635    void enforceCallingPermission(String permission, String func) {
7636        if (checkCallingPermission(permission)
7637                == PackageManager.PERMISSION_GRANTED) {
7638            return;
7639        }
7640
7641        String msg = "Permission Denial: " + func + " from pid="
7642                + Binder.getCallingPid()
7643                + ", uid=" + Binder.getCallingUid()
7644                + " requires " + permission;
7645        Slog.w(TAG, msg);
7646        throw new SecurityException(msg);
7647    }
7648
7649    /**
7650     * Determine if UID is holding permissions required to access {@link Uri} in
7651     * the given {@link ProviderInfo}. Final permission checking is always done
7652     * in {@link ContentProvider}.
7653     */
7654    private final boolean checkHoldingPermissionsLocked(
7655            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7656        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7657                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7658        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7659            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7660                    != PERMISSION_GRANTED) {
7661                return false;
7662            }
7663        }
7664        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7665    }
7666
7667    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7668            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7669        if (pi.applicationInfo.uid == uid) {
7670            return true;
7671        } else if (!pi.exported) {
7672            return false;
7673        }
7674
7675        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7676        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7677        try {
7678            // check if target holds top-level <provider> permissions
7679            if (!readMet && pi.readPermission != null && considerUidPermissions
7680                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7681                readMet = true;
7682            }
7683            if (!writeMet && pi.writePermission != null && considerUidPermissions
7684                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7685                writeMet = true;
7686            }
7687
7688            // track if unprotected read/write is allowed; any denied
7689            // <path-permission> below removes this ability
7690            boolean allowDefaultRead = pi.readPermission == null;
7691            boolean allowDefaultWrite = pi.writePermission == null;
7692
7693            // check if target holds any <path-permission> that match uri
7694            final PathPermission[] pps = pi.pathPermissions;
7695            if (pps != null) {
7696                final String path = grantUri.uri.getPath();
7697                int i = pps.length;
7698                while (i > 0 && (!readMet || !writeMet)) {
7699                    i--;
7700                    PathPermission pp = pps[i];
7701                    if (pp.match(path)) {
7702                        if (!readMet) {
7703                            final String pprperm = pp.getReadPermission();
7704                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7705                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7706                                    + ": match=" + pp.match(path)
7707                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7708                            if (pprperm != null) {
7709                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7710                                        == PERMISSION_GRANTED) {
7711                                    readMet = true;
7712                                } else {
7713                                    allowDefaultRead = false;
7714                                }
7715                            }
7716                        }
7717                        if (!writeMet) {
7718                            final String ppwperm = pp.getWritePermission();
7719                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7720                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7721                                    + ": match=" + pp.match(path)
7722                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7723                            if (ppwperm != null) {
7724                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7725                                        == PERMISSION_GRANTED) {
7726                                    writeMet = true;
7727                                } else {
7728                                    allowDefaultWrite = false;
7729                                }
7730                            }
7731                        }
7732                    }
7733                }
7734            }
7735
7736            // grant unprotected <provider> read/write, if not blocked by
7737            // <path-permission> above
7738            if (allowDefaultRead) readMet = true;
7739            if (allowDefaultWrite) writeMet = true;
7740
7741        } catch (RemoteException e) {
7742            return false;
7743        }
7744
7745        return readMet && writeMet;
7746    }
7747
7748    public int getAppStartMode(int uid, String packageName) {
7749        synchronized (this) {
7750            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7751        }
7752    }
7753
7754    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7755            boolean allowWhenForeground) {
7756        UidRecord uidRec = mActiveUids.get(uid);
7757        if (!mLenientBackgroundCheck) {
7758            if (!allowWhenForeground || uidRec == null
7759                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7760                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7761                        packageName) != AppOpsManager.MODE_ALLOWED) {
7762                    return ActivityManager.APP_START_MODE_DELAYED;
7763                }
7764            }
7765
7766        } else if (uidRec == null || uidRec.idle) {
7767            if (callingPid >= 0) {
7768                ProcessRecord proc;
7769                synchronized (mPidsSelfLocked) {
7770                    proc = mPidsSelfLocked.get(callingPid);
7771                }
7772                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7773                    // Whoever is instigating this is in the foreground, so we will allow it
7774                    // to go through.
7775                    return ActivityManager.APP_START_MODE_NORMAL;
7776                }
7777            }
7778            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7779                    != AppOpsManager.MODE_ALLOWED) {
7780                return ActivityManager.APP_START_MODE_DELAYED;
7781            }
7782        }
7783        return ActivityManager.APP_START_MODE_NORMAL;
7784    }
7785
7786    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7787        ProviderInfo pi = null;
7788        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7789        if (cpr != null) {
7790            pi = cpr.info;
7791        } else {
7792            try {
7793                pi = AppGlobals.getPackageManager().resolveContentProvider(
7794                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7795            } catch (RemoteException ex) {
7796            }
7797        }
7798        return pi;
7799    }
7800
7801    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7802        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7803        if (targetUris != null) {
7804            return targetUris.get(grantUri);
7805        }
7806        return null;
7807    }
7808
7809    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7810            String targetPkg, int targetUid, GrantUri grantUri) {
7811        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7812        if (targetUris == null) {
7813            targetUris = Maps.newArrayMap();
7814            mGrantedUriPermissions.put(targetUid, targetUris);
7815        }
7816
7817        UriPermission perm = targetUris.get(grantUri);
7818        if (perm == null) {
7819            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7820            targetUris.put(grantUri, perm);
7821        }
7822
7823        return perm;
7824    }
7825
7826    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7827            final int modeFlags) {
7828        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7829        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7830                : UriPermission.STRENGTH_OWNED;
7831
7832        // Root gets to do everything.
7833        if (uid == 0) {
7834            return true;
7835        }
7836
7837        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7838        if (perms == null) return false;
7839
7840        // First look for exact match
7841        final UriPermission exactPerm = perms.get(grantUri);
7842        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7843            return true;
7844        }
7845
7846        // No exact match, look for prefixes
7847        final int N = perms.size();
7848        for (int i = 0; i < N; i++) {
7849            final UriPermission perm = perms.valueAt(i);
7850            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7851                    && perm.getStrength(modeFlags) >= minStrength) {
7852                return true;
7853            }
7854        }
7855
7856        return false;
7857    }
7858
7859    /**
7860     * @param uri This uri must NOT contain an embedded userId.
7861     * @param userId The userId in which the uri is to be resolved.
7862     */
7863    @Override
7864    public int checkUriPermission(Uri uri, int pid, int uid,
7865            final int modeFlags, int userId, IBinder callerToken) {
7866        enforceNotIsolatedCaller("checkUriPermission");
7867
7868        // Another redirected-binder-call permissions check as in
7869        // {@link checkPermissionWithToken}.
7870        Identity tlsIdentity = sCallerIdentity.get();
7871        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7872            uid = tlsIdentity.uid;
7873            pid = tlsIdentity.pid;
7874        }
7875
7876        // Our own process gets to do everything.
7877        if (pid == MY_PID) {
7878            return PackageManager.PERMISSION_GRANTED;
7879        }
7880        synchronized (this) {
7881            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7882                    ? PackageManager.PERMISSION_GRANTED
7883                    : PackageManager.PERMISSION_DENIED;
7884        }
7885    }
7886
7887    /**
7888     * Check if the targetPkg can be granted permission to access uri by
7889     * the callingUid using the given modeFlags.  Throws a security exception
7890     * if callingUid is not allowed to do this.  Returns the uid of the target
7891     * if the URI permission grant should be performed; returns -1 if it is not
7892     * needed (for example targetPkg already has permission to access the URI).
7893     * If you already know the uid of the target, you can supply it in
7894     * lastTargetUid else set that to -1.
7895     */
7896    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7897            final int modeFlags, int lastTargetUid) {
7898        if (!Intent.isAccessUriMode(modeFlags)) {
7899            return -1;
7900        }
7901
7902        if (targetPkg != null) {
7903            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7904                    "Checking grant " + targetPkg + " permission to " + grantUri);
7905        }
7906
7907        final IPackageManager pm = AppGlobals.getPackageManager();
7908
7909        // If this is not a content: uri, we can't do anything with it.
7910        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7911            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7912                    "Can't grant URI permission for non-content URI: " + grantUri);
7913            return -1;
7914        }
7915
7916        final String authority = grantUri.uri.getAuthority();
7917        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7918        if (pi == null) {
7919            Slog.w(TAG, "No content provider found for permission check: " +
7920                    grantUri.uri.toSafeString());
7921            return -1;
7922        }
7923
7924        int targetUid = lastTargetUid;
7925        if (targetUid < 0 && targetPkg != null) {
7926            try {
7927                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7928                        UserHandle.getUserId(callingUid));
7929                if (targetUid < 0) {
7930                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7931                            "Can't grant URI permission no uid for: " + targetPkg);
7932                    return -1;
7933                }
7934            } catch (RemoteException ex) {
7935                return -1;
7936            }
7937        }
7938
7939        if (targetUid >= 0) {
7940            // First...  does the target actually need this permission?
7941            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7942                // No need to grant the target this permission.
7943                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7944                        "Target " + targetPkg + " already has full permission to " + grantUri);
7945                return -1;
7946            }
7947        } else {
7948            // First...  there is no target package, so can anyone access it?
7949            boolean allowed = pi.exported;
7950            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7951                if (pi.readPermission != null) {
7952                    allowed = false;
7953                }
7954            }
7955            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7956                if (pi.writePermission != null) {
7957                    allowed = false;
7958                }
7959            }
7960            if (allowed) {
7961                return -1;
7962            }
7963        }
7964
7965        /* There is a special cross user grant if:
7966         * - The target is on another user.
7967         * - Apps on the current user can access the uri without any uid permissions.
7968         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7969         * grant uri permissions.
7970         */
7971        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7972                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7973                modeFlags, false /*without considering the uid permissions*/);
7974
7975        // Second...  is the provider allowing granting of URI permissions?
7976        if (!specialCrossUserGrant) {
7977            if (!pi.grantUriPermissions) {
7978                throw new SecurityException("Provider " + pi.packageName
7979                        + "/" + pi.name
7980                        + " does not allow granting of Uri permissions (uri "
7981                        + grantUri + ")");
7982            }
7983            if (pi.uriPermissionPatterns != null) {
7984                final int N = pi.uriPermissionPatterns.length;
7985                boolean allowed = false;
7986                for (int i=0; i<N; i++) {
7987                    if (pi.uriPermissionPatterns[i] != null
7988                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7989                        allowed = true;
7990                        break;
7991                    }
7992                }
7993                if (!allowed) {
7994                    throw new SecurityException("Provider " + pi.packageName
7995                            + "/" + pi.name
7996                            + " does not allow granting of permission to path of Uri "
7997                            + grantUri);
7998                }
7999            }
8000        }
8001
8002        // Third...  does the caller itself have permission to access
8003        // this uri?
8004        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
8005            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8006                // Require they hold a strong enough Uri permission
8007                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8008                    throw new SecurityException("Uid " + callingUid
8009                            + " does not have permission to uri " + grantUri);
8010                }
8011            }
8012        }
8013        return targetUid;
8014    }
8015
8016    /**
8017     * @param uri This uri must NOT contain an embedded userId.
8018     * @param userId The userId in which the uri is to be resolved.
8019     */
8020    @Override
8021    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8022            final int modeFlags, int userId) {
8023        enforceNotIsolatedCaller("checkGrantUriPermission");
8024        synchronized(this) {
8025            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8026                    new GrantUri(userId, uri, false), modeFlags, -1);
8027        }
8028    }
8029
8030    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8031            final int modeFlags, UriPermissionOwner owner) {
8032        if (!Intent.isAccessUriMode(modeFlags)) {
8033            return;
8034        }
8035
8036        // So here we are: the caller has the assumed permission
8037        // to the uri, and the target doesn't.  Let's now give this to
8038        // the target.
8039
8040        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8041                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8042
8043        final String authority = grantUri.uri.getAuthority();
8044        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8045        if (pi == null) {
8046            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8047            return;
8048        }
8049
8050        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8051            grantUri.prefix = true;
8052        }
8053        final UriPermission perm = findOrCreateUriPermissionLocked(
8054                pi.packageName, targetPkg, targetUid, grantUri);
8055        perm.grantModes(modeFlags, owner);
8056    }
8057
8058    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8059            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8060        if (targetPkg == null) {
8061            throw new NullPointerException("targetPkg");
8062        }
8063        int targetUid;
8064        final IPackageManager pm = AppGlobals.getPackageManager();
8065        try {
8066            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8067        } catch (RemoteException ex) {
8068            return;
8069        }
8070
8071        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8072                targetUid);
8073        if (targetUid < 0) {
8074            return;
8075        }
8076
8077        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8078                owner);
8079    }
8080
8081    static class NeededUriGrants extends ArrayList<GrantUri> {
8082        final String targetPkg;
8083        final int targetUid;
8084        final int flags;
8085
8086        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8087            this.targetPkg = targetPkg;
8088            this.targetUid = targetUid;
8089            this.flags = flags;
8090        }
8091    }
8092
8093    /**
8094     * Like checkGrantUriPermissionLocked, but takes an Intent.
8095     */
8096    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8097            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8098        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8099                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8100                + " clip=" + (intent != null ? intent.getClipData() : null)
8101                + " from " + intent + "; flags=0x"
8102                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8103
8104        if (targetPkg == null) {
8105            throw new NullPointerException("targetPkg");
8106        }
8107
8108        if (intent == null) {
8109            return null;
8110        }
8111        Uri data = intent.getData();
8112        ClipData clip = intent.getClipData();
8113        if (data == null && clip == null) {
8114            return null;
8115        }
8116        // Default userId for uris in the intent (if they don't specify it themselves)
8117        int contentUserHint = intent.getContentUserHint();
8118        if (contentUserHint == UserHandle.USER_CURRENT) {
8119            contentUserHint = UserHandle.getUserId(callingUid);
8120        }
8121        final IPackageManager pm = AppGlobals.getPackageManager();
8122        int targetUid;
8123        if (needed != null) {
8124            targetUid = needed.targetUid;
8125        } else {
8126            try {
8127                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8128                        targetUserId);
8129            } catch (RemoteException ex) {
8130                return null;
8131            }
8132            if (targetUid < 0) {
8133                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8134                        "Can't grant URI permission no uid for: " + targetPkg
8135                        + " on user " + targetUserId);
8136                return null;
8137            }
8138        }
8139        if (data != null) {
8140            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8141            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8142                    targetUid);
8143            if (targetUid > 0) {
8144                if (needed == null) {
8145                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8146                }
8147                needed.add(grantUri);
8148            }
8149        }
8150        if (clip != null) {
8151            for (int i=0; i<clip.getItemCount(); i++) {
8152                Uri uri = clip.getItemAt(i).getUri();
8153                if (uri != null) {
8154                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8155                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8156                            targetUid);
8157                    if (targetUid > 0) {
8158                        if (needed == null) {
8159                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8160                        }
8161                        needed.add(grantUri);
8162                    }
8163                } else {
8164                    Intent clipIntent = clip.getItemAt(i).getIntent();
8165                    if (clipIntent != null) {
8166                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8167                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8168                        if (newNeeded != null) {
8169                            needed = newNeeded;
8170                        }
8171                    }
8172                }
8173            }
8174        }
8175
8176        return needed;
8177    }
8178
8179    /**
8180     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8181     */
8182    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8183            UriPermissionOwner owner) {
8184        if (needed != null) {
8185            for (int i=0; i<needed.size(); i++) {
8186                GrantUri grantUri = needed.get(i);
8187                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8188                        grantUri, needed.flags, owner);
8189            }
8190        }
8191    }
8192
8193    void grantUriPermissionFromIntentLocked(int callingUid,
8194            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8195        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8196                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8197        if (needed == null) {
8198            return;
8199        }
8200
8201        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8202    }
8203
8204    /**
8205     * @param uri This uri must NOT contain an embedded userId.
8206     * @param userId The userId in which the uri is to be resolved.
8207     */
8208    @Override
8209    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8210            final int modeFlags, int userId) {
8211        enforceNotIsolatedCaller("grantUriPermission");
8212        GrantUri grantUri = new GrantUri(userId, uri, false);
8213        synchronized(this) {
8214            final ProcessRecord r = getRecordForAppLocked(caller);
8215            if (r == null) {
8216                throw new SecurityException("Unable to find app for caller "
8217                        + caller
8218                        + " when granting permission to uri " + grantUri);
8219            }
8220            if (targetPkg == null) {
8221                throw new IllegalArgumentException("null target");
8222            }
8223            if (grantUri == null) {
8224                throw new IllegalArgumentException("null uri");
8225            }
8226
8227            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8228                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8229                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8230                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8231
8232            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8233                    UserHandle.getUserId(r.uid));
8234        }
8235    }
8236
8237    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8238        if (perm.modeFlags == 0) {
8239            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8240                    perm.targetUid);
8241            if (perms != null) {
8242                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8243                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8244
8245                perms.remove(perm.uri);
8246                if (perms.isEmpty()) {
8247                    mGrantedUriPermissions.remove(perm.targetUid);
8248                }
8249            }
8250        }
8251    }
8252
8253    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8254        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8255                "Revoking all granted permissions to " + grantUri);
8256
8257        final IPackageManager pm = AppGlobals.getPackageManager();
8258        final String authority = grantUri.uri.getAuthority();
8259        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8260        if (pi == null) {
8261            Slog.w(TAG, "No content provider found for permission revoke: "
8262                    + grantUri.toSafeString());
8263            return;
8264        }
8265
8266        // Does the caller have this permission on the URI?
8267        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8268            // If they don't have direct access to the URI, then revoke any
8269            // ownerless URI permissions that have been granted to them.
8270            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8271            if (perms != null) {
8272                boolean persistChanged = false;
8273                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8274                    final UriPermission perm = it.next();
8275                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8276                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8277                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8278                                "Revoking non-owned " + perm.targetUid
8279                                + " permission to " + perm.uri);
8280                        persistChanged |= perm.revokeModes(
8281                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8282                        if (perm.modeFlags == 0) {
8283                            it.remove();
8284                        }
8285                    }
8286                }
8287                if (perms.isEmpty()) {
8288                    mGrantedUriPermissions.remove(callingUid);
8289                }
8290                if (persistChanged) {
8291                    schedulePersistUriGrants();
8292                }
8293            }
8294            return;
8295        }
8296
8297        boolean persistChanged = false;
8298
8299        // Go through all of the permissions and remove any that match.
8300        int N = mGrantedUriPermissions.size();
8301        for (int i = 0; i < N; i++) {
8302            final int targetUid = mGrantedUriPermissions.keyAt(i);
8303            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8304
8305            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8306                final UriPermission perm = it.next();
8307                if (perm.uri.sourceUserId == grantUri.sourceUserId
8308                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8309                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8310                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8311                    persistChanged |= perm.revokeModes(
8312                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8313                    if (perm.modeFlags == 0) {
8314                        it.remove();
8315                    }
8316                }
8317            }
8318
8319            if (perms.isEmpty()) {
8320                mGrantedUriPermissions.remove(targetUid);
8321                N--;
8322                i--;
8323            }
8324        }
8325
8326        if (persistChanged) {
8327            schedulePersistUriGrants();
8328        }
8329    }
8330
8331    /**
8332     * @param uri This uri must NOT contain an embedded userId.
8333     * @param userId The userId in which the uri is to be resolved.
8334     */
8335    @Override
8336    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8337            int userId) {
8338        enforceNotIsolatedCaller("revokeUriPermission");
8339        synchronized(this) {
8340            final ProcessRecord r = getRecordForAppLocked(caller);
8341            if (r == null) {
8342                throw new SecurityException("Unable to find app for caller "
8343                        + caller
8344                        + " when revoking permission to uri " + uri);
8345            }
8346            if (uri == null) {
8347                Slog.w(TAG, "revokeUriPermission: null uri");
8348                return;
8349            }
8350
8351            if (!Intent.isAccessUriMode(modeFlags)) {
8352                return;
8353            }
8354
8355            final String authority = uri.getAuthority();
8356            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
8357            if (pi == null) {
8358                Slog.w(TAG, "No content provider found for permission revoke: "
8359                        + uri.toSafeString());
8360                return;
8361            }
8362
8363            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8364        }
8365    }
8366
8367    /**
8368     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8369     * given package.
8370     *
8371     * @param packageName Package name to match, or {@code null} to apply to all
8372     *            packages.
8373     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8374     *            to all users.
8375     * @param persistable If persistable grants should be removed.
8376     */
8377    private void removeUriPermissionsForPackageLocked(
8378            String packageName, int userHandle, boolean persistable) {
8379        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8380            throw new IllegalArgumentException("Must narrow by either package or user");
8381        }
8382
8383        boolean persistChanged = false;
8384
8385        int N = mGrantedUriPermissions.size();
8386        for (int i = 0; i < N; i++) {
8387            final int targetUid = mGrantedUriPermissions.keyAt(i);
8388            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8389
8390            // Only inspect grants matching user
8391            if (userHandle == UserHandle.USER_ALL
8392                    || userHandle == UserHandle.getUserId(targetUid)) {
8393                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8394                    final UriPermission perm = it.next();
8395
8396                    // Only inspect grants matching package
8397                    if (packageName == null || perm.sourcePkg.equals(packageName)
8398                            || perm.targetPkg.equals(packageName)) {
8399                        persistChanged |= perm.revokeModes(persistable
8400                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8401
8402                        // Only remove when no modes remain; any persisted grants
8403                        // will keep this alive.
8404                        if (perm.modeFlags == 0) {
8405                            it.remove();
8406                        }
8407                    }
8408                }
8409
8410                if (perms.isEmpty()) {
8411                    mGrantedUriPermissions.remove(targetUid);
8412                    N--;
8413                    i--;
8414                }
8415            }
8416        }
8417
8418        if (persistChanged) {
8419            schedulePersistUriGrants();
8420        }
8421    }
8422
8423    @Override
8424    public IBinder newUriPermissionOwner(String name) {
8425        enforceNotIsolatedCaller("newUriPermissionOwner");
8426        synchronized(this) {
8427            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8428            return owner.getExternalTokenLocked();
8429        }
8430    }
8431
8432    @Override
8433    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8434        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8435        synchronized(this) {
8436            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8437            if (r == null) {
8438                throw new IllegalArgumentException("Activity does not exist; token="
8439                        + activityToken);
8440            }
8441            return r.getUriPermissionsLocked().getExternalTokenLocked();
8442        }
8443    }
8444    /**
8445     * @param uri This uri must NOT contain an embedded userId.
8446     * @param sourceUserId The userId in which the uri is to be resolved.
8447     * @param targetUserId The userId of the app that receives the grant.
8448     */
8449    @Override
8450    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8451            final int modeFlags, int sourceUserId, int targetUserId) {
8452        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8453                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8454                "grantUriPermissionFromOwner", null);
8455        synchronized(this) {
8456            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8457            if (owner == null) {
8458                throw new IllegalArgumentException("Unknown owner: " + token);
8459            }
8460            if (fromUid != Binder.getCallingUid()) {
8461                if (Binder.getCallingUid() != Process.myUid()) {
8462                    // Only system code can grant URI permissions on behalf
8463                    // of other users.
8464                    throw new SecurityException("nice try");
8465                }
8466            }
8467            if (targetPkg == null) {
8468                throw new IllegalArgumentException("null target");
8469            }
8470            if (uri == null) {
8471                throw new IllegalArgumentException("null uri");
8472            }
8473
8474            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8475                    modeFlags, owner, targetUserId);
8476        }
8477    }
8478
8479    /**
8480     * @param uri This uri must NOT contain an embedded userId.
8481     * @param userId The userId in which the uri is to be resolved.
8482     */
8483    @Override
8484    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8485        synchronized(this) {
8486            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8487            if (owner == null) {
8488                throw new IllegalArgumentException("Unknown owner: " + token);
8489            }
8490
8491            if (uri == null) {
8492                owner.removeUriPermissionsLocked(mode);
8493            } else {
8494                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8495            }
8496        }
8497    }
8498
8499    private void schedulePersistUriGrants() {
8500        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8501            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8502                    10 * DateUtils.SECOND_IN_MILLIS);
8503        }
8504    }
8505
8506    private void writeGrantedUriPermissions() {
8507        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8508
8509        // Snapshot permissions so we can persist without lock
8510        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8511        synchronized (this) {
8512            final int size = mGrantedUriPermissions.size();
8513            for (int i = 0; i < size; i++) {
8514                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8515                for (UriPermission perm : perms.values()) {
8516                    if (perm.persistedModeFlags != 0) {
8517                        persist.add(perm.snapshot());
8518                    }
8519                }
8520            }
8521        }
8522
8523        FileOutputStream fos = null;
8524        try {
8525            fos = mGrantFile.startWrite();
8526
8527            XmlSerializer out = new FastXmlSerializer();
8528            out.setOutput(fos, StandardCharsets.UTF_8.name());
8529            out.startDocument(null, true);
8530            out.startTag(null, TAG_URI_GRANTS);
8531            for (UriPermission.Snapshot perm : persist) {
8532                out.startTag(null, TAG_URI_GRANT);
8533                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8534                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8535                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8536                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8537                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8538                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8539                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8540                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8541                out.endTag(null, TAG_URI_GRANT);
8542            }
8543            out.endTag(null, TAG_URI_GRANTS);
8544            out.endDocument();
8545
8546            mGrantFile.finishWrite(fos);
8547        } catch (IOException e) {
8548            if (fos != null) {
8549                mGrantFile.failWrite(fos);
8550            }
8551        }
8552    }
8553
8554    private void readGrantedUriPermissionsLocked() {
8555        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8556
8557        final long now = System.currentTimeMillis();
8558
8559        FileInputStream fis = null;
8560        try {
8561            fis = mGrantFile.openRead();
8562            final XmlPullParser in = Xml.newPullParser();
8563            in.setInput(fis, StandardCharsets.UTF_8.name());
8564
8565            int type;
8566            while ((type = in.next()) != END_DOCUMENT) {
8567                final String tag = in.getName();
8568                if (type == START_TAG) {
8569                    if (TAG_URI_GRANT.equals(tag)) {
8570                        final int sourceUserId;
8571                        final int targetUserId;
8572                        final int userHandle = readIntAttribute(in,
8573                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8574                        if (userHandle != UserHandle.USER_NULL) {
8575                            // For backwards compatibility.
8576                            sourceUserId = userHandle;
8577                            targetUserId = userHandle;
8578                        } else {
8579                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8580                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8581                        }
8582                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8583                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8584                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8585                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8586                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8587                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8588
8589                        // Sanity check that provider still belongs to source package
8590                        final ProviderInfo pi = getProviderInfoLocked(
8591                                uri.getAuthority(), sourceUserId);
8592                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8593                            int targetUid = -1;
8594                            try {
8595                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8596                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8597                            } catch (RemoteException e) {
8598                            }
8599                            if (targetUid != -1) {
8600                                final UriPermission perm = findOrCreateUriPermissionLocked(
8601                                        sourcePkg, targetPkg, targetUid,
8602                                        new GrantUri(sourceUserId, uri, prefix));
8603                                perm.initPersistedModes(modeFlags, createdTime);
8604                            }
8605                        } else {
8606                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8607                                    + " but instead found " + pi);
8608                        }
8609                    }
8610                }
8611            }
8612        } catch (FileNotFoundException e) {
8613            // Missing grants is okay
8614        } catch (IOException e) {
8615            Slog.wtf(TAG, "Failed reading Uri grants", e);
8616        } catch (XmlPullParserException e) {
8617            Slog.wtf(TAG, "Failed reading Uri grants", e);
8618        } finally {
8619            IoUtils.closeQuietly(fis);
8620        }
8621    }
8622
8623    /**
8624     * @param uri This uri must NOT contain an embedded userId.
8625     * @param userId The userId in which the uri is to be resolved.
8626     */
8627    @Override
8628    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8629        enforceNotIsolatedCaller("takePersistableUriPermission");
8630
8631        Preconditions.checkFlagsArgument(modeFlags,
8632                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8633
8634        synchronized (this) {
8635            final int callingUid = Binder.getCallingUid();
8636            boolean persistChanged = false;
8637            GrantUri grantUri = new GrantUri(userId, uri, false);
8638
8639            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8640                    new GrantUri(userId, uri, false));
8641            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8642                    new GrantUri(userId, uri, true));
8643
8644            final boolean exactValid = (exactPerm != null)
8645                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8646            final boolean prefixValid = (prefixPerm != null)
8647                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8648
8649            if (!(exactValid || prefixValid)) {
8650                throw new SecurityException("No persistable permission grants found for UID "
8651                        + callingUid + " and Uri " + grantUri.toSafeString());
8652            }
8653
8654            if (exactValid) {
8655                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8656            }
8657            if (prefixValid) {
8658                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8659            }
8660
8661            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8662
8663            if (persistChanged) {
8664                schedulePersistUriGrants();
8665            }
8666        }
8667    }
8668
8669    /**
8670     * @param uri This uri must NOT contain an embedded userId.
8671     * @param userId The userId in which the uri is to be resolved.
8672     */
8673    @Override
8674    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8675        enforceNotIsolatedCaller("releasePersistableUriPermission");
8676
8677        Preconditions.checkFlagsArgument(modeFlags,
8678                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8679
8680        synchronized (this) {
8681            final int callingUid = Binder.getCallingUid();
8682            boolean persistChanged = false;
8683
8684            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8685                    new GrantUri(userId, uri, false));
8686            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8687                    new GrantUri(userId, uri, true));
8688            if (exactPerm == null && prefixPerm == null) {
8689                throw new SecurityException("No permission grants found for UID " + callingUid
8690                        + " and Uri " + uri.toSafeString());
8691            }
8692
8693            if (exactPerm != null) {
8694                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8695                removeUriPermissionIfNeededLocked(exactPerm);
8696            }
8697            if (prefixPerm != null) {
8698                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8699                removeUriPermissionIfNeededLocked(prefixPerm);
8700            }
8701
8702            if (persistChanged) {
8703                schedulePersistUriGrants();
8704            }
8705        }
8706    }
8707
8708    /**
8709     * Prune any older {@link UriPermission} for the given UID until outstanding
8710     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8711     *
8712     * @return if any mutations occured that require persisting.
8713     */
8714    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8715        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8716        if (perms == null) return false;
8717        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8718
8719        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8720        for (UriPermission perm : perms.values()) {
8721            if (perm.persistedModeFlags != 0) {
8722                persisted.add(perm);
8723            }
8724        }
8725
8726        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8727        if (trimCount <= 0) return false;
8728
8729        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8730        for (int i = 0; i < trimCount; i++) {
8731            final UriPermission perm = persisted.get(i);
8732
8733            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8734                    "Trimming grant created at " + perm.persistedCreateTime);
8735
8736            perm.releasePersistableModes(~0);
8737            removeUriPermissionIfNeededLocked(perm);
8738        }
8739
8740        return true;
8741    }
8742
8743    @Override
8744    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8745            String packageName, boolean incoming) {
8746        enforceNotIsolatedCaller("getPersistedUriPermissions");
8747        Preconditions.checkNotNull(packageName, "packageName");
8748
8749        final int callingUid = Binder.getCallingUid();
8750        final IPackageManager pm = AppGlobals.getPackageManager();
8751        try {
8752            final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
8753                    UserHandle.getUserId(callingUid));
8754            if (packageUid != callingUid) {
8755                throw new SecurityException(
8756                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8757            }
8758        } catch (RemoteException e) {
8759            throw new SecurityException("Failed to verify package name ownership");
8760        }
8761
8762        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8763        synchronized (this) {
8764            if (incoming) {
8765                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8766                        callingUid);
8767                if (perms == null) {
8768                    Slog.w(TAG, "No permission grants found for " + packageName);
8769                } else {
8770                    for (UriPermission perm : perms.values()) {
8771                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8772                            result.add(perm.buildPersistedPublicApiObject());
8773                        }
8774                    }
8775                }
8776            } else {
8777                final int size = mGrantedUriPermissions.size();
8778                for (int i = 0; i < size; i++) {
8779                    final ArrayMap<GrantUri, UriPermission> perms =
8780                            mGrantedUriPermissions.valueAt(i);
8781                    for (UriPermission perm : perms.values()) {
8782                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8783                            result.add(perm.buildPersistedPublicApiObject());
8784                        }
8785                    }
8786                }
8787            }
8788        }
8789        return new ParceledListSlice<android.content.UriPermission>(result);
8790    }
8791
8792    @Override
8793    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8794            String packageName, int userId) {
8795        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8796                "getGrantedUriPermissions");
8797
8798        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8799        synchronized (this) {
8800            final int size = mGrantedUriPermissions.size();
8801            for (int i = 0; i < size; i++) {
8802                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8803                for (UriPermission perm : perms.values()) {
8804                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8805                            && perm.persistedModeFlags != 0) {
8806                        result.add(perm.buildPersistedPublicApiObject());
8807                    }
8808                }
8809            }
8810        }
8811        return new ParceledListSlice<android.content.UriPermission>(result);
8812    }
8813
8814    @Override
8815    public void clearGrantedUriPermissions(String packageName, int userId) {
8816        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8817                "clearGrantedUriPermissions");
8818        removeUriPermissionsForPackageLocked(packageName, userId, true);
8819    }
8820
8821    @Override
8822    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8823        synchronized (this) {
8824            ProcessRecord app =
8825                who != null ? getRecordForAppLocked(who) : null;
8826            if (app == null) return;
8827
8828            Message msg = Message.obtain();
8829            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8830            msg.obj = app;
8831            msg.arg1 = waiting ? 1 : 0;
8832            mUiHandler.sendMessage(msg);
8833        }
8834    }
8835
8836    @Override
8837    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8838        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8839        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8840        outInfo.availMem = Process.getFreeMemory();
8841        outInfo.totalMem = Process.getTotalMemory();
8842        outInfo.threshold = homeAppMem;
8843        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8844        outInfo.hiddenAppThreshold = cachedAppMem;
8845        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8846                ProcessList.SERVICE_ADJ);
8847        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8848                ProcessList.VISIBLE_APP_ADJ);
8849        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8850                ProcessList.FOREGROUND_APP_ADJ);
8851    }
8852
8853    // =========================================================
8854    // TASK MANAGEMENT
8855    // =========================================================
8856
8857    @Override
8858    public List<IAppTask> getAppTasks(String callingPackage) {
8859        int callingUid = Binder.getCallingUid();
8860        long ident = Binder.clearCallingIdentity();
8861
8862        synchronized(this) {
8863            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8864            try {
8865                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8866
8867                final int N = mRecentTasks.size();
8868                for (int i = 0; i < N; i++) {
8869                    TaskRecord tr = mRecentTasks.get(i);
8870                    // Skip tasks that do not match the caller.  We don't need to verify
8871                    // callingPackage, because we are also limiting to callingUid and know
8872                    // that will limit to the correct security sandbox.
8873                    if (tr.effectiveUid != callingUid) {
8874                        continue;
8875                    }
8876                    Intent intent = tr.getBaseIntent();
8877                    if (intent == null ||
8878                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8879                        continue;
8880                    }
8881                    ActivityManager.RecentTaskInfo taskInfo =
8882                            createRecentTaskInfoFromTaskRecord(tr);
8883                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8884                    list.add(taskImpl);
8885                }
8886            } finally {
8887                Binder.restoreCallingIdentity(ident);
8888            }
8889            return list;
8890        }
8891    }
8892
8893    @Override
8894    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8895        final int callingUid = Binder.getCallingUid();
8896        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8897
8898        synchronized(this) {
8899            if (DEBUG_ALL) Slog.v(
8900                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8901
8902            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8903                    callingUid);
8904
8905            // TODO: Improve with MRU list from all ActivityStacks.
8906            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8907        }
8908
8909        return list;
8910    }
8911
8912    /**
8913     * Creates a new RecentTaskInfo from a TaskRecord.
8914     */
8915    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8916        // Update the task description to reflect any changes in the task stack
8917        tr.updateTaskDescription();
8918
8919        // Compose the recent task info
8920        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8921        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8922        rti.persistentId = tr.taskId;
8923        rti.baseIntent = new Intent(tr.getBaseIntent());
8924        rti.origActivity = tr.origActivity;
8925        rti.realActivity = tr.realActivity;
8926        rti.description = tr.lastDescription;
8927        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8928        rti.userId = tr.userId;
8929        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8930        rti.firstActiveTime = tr.firstActiveTime;
8931        rti.lastActiveTime = tr.lastActiveTime;
8932        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8933        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8934        rti.numActivities = 0;
8935        if (tr.mBounds != null) {
8936            rti.bounds = new Rect(tr.mBounds);
8937        }
8938        rti.isDockable = tr.canGoInDockedStack();
8939        rti.resizeMode = tr.mResizeMode;
8940
8941        ActivityRecord base = null;
8942        ActivityRecord top = null;
8943        ActivityRecord tmp;
8944
8945        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8946            tmp = tr.mActivities.get(i);
8947            if (tmp.finishing) {
8948                continue;
8949            }
8950            base = tmp;
8951            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8952                top = base;
8953            }
8954            rti.numActivities++;
8955        }
8956
8957        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8958        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8959
8960        return rti;
8961    }
8962
8963    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8964        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8965                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8966        if (!allowed) {
8967            if (checkPermission(android.Manifest.permission.GET_TASKS,
8968                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8969                // Temporary compatibility: some existing apps on the system image may
8970                // still be requesting the old permission and not switched to the new
8971                // one; if so, we'll still allow them full access.  This means we need
8972                // to see if they are holding the old permission and are a system app.
8973                try {
8974                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8975                        allowed = true;
8976                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8977                                + " is using old GET_TASKS but privileged; allowing");
8978                    }
8979                } catch (RemoteException e) {
8980                }
8981            }
8982        }
8983        if (!allowed) {
8984            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8985                    + " does not hold REAL_GET_TASKS; limiting output");
8986        }
8987        return allowed;
8988    }
8989
8990    @Override
8991    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8992        final int callingUid = Binder.getCallingUid();
8993        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8994                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8995
8996        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8997        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8998        synchronized (this) {
8999            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9000                    callingUid);
9001            final boolean detailed = checkCallingPermission(
9002                    android.Manifest.permission.GET_DETAILED_TASKS)
9003                    == PackageManager.PERMISSION_GRANTED;
9004
9005            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9006                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9007                return Collections.emptyList();
9008            }
9009            mRecentTasks.loadUserRecentsLocked(userId);
9010
9011            final int recentsCount = mRecentTasks.size();
9012            ArrayList<ActivityManager.RecentTaskInfo> res =
9013                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9014
9015            final Set<Integer> includedUsers;
9016            if (includeProfiles) {
9017                includedUsers = mUserController.getProfileIds(userId);
9018            } else {
9019                includedUsers = new HashSet<>();
9020            }
9021            includedUsers.add(Integer.valueOf(userId));
9022
9023            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9024                TaskRecord tr = mRecentTasks.get(i);
9025                // Only add calling user or related users recent tasks
9026                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9027                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9028                    continue;
9029                }
9030
9031                if (tr.realActivitySuspended) {
9032                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9033                    continue;
9034                }
9035
9036                // Return the entry if desired by the caller.  We always return
9037                // the first entry, because callers always expect this to be the
9038                // foreground app.  We may filter others if the caller has
9039                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9040                // we should exclude the entry.
9041
9042                if (i == 0
9043                        || withExcluded
9044                        || (tr.intent == null)
9045                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9046                                == 0)) {
9047                    if (!allowed) {
9048                        // If the caller doesn't have the GET_TASKS permission, then only
9049                        // allow them to see a small subset of tasks -- their own and home.
9050                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9051                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9052                            continue;
9053                        }
9054                    }
9055                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9056                        if (tr.stack != null && tr.stack.isHomeStack()) {
9057                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9058                                    "Skipping, home stack task: " + tr);
9059                            continue;
9060                        }
9061                    }
9062                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9063                        final ActivityStack stack = tr.stack;
9064                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9065                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9066                                    "Skipping, top task in docked stack: " + tr);
9067                            continue;
9068                        }
9069                    }
9070                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9071                        if (tr.stack != null && tr.stack.isPinnedStack()) {
9072                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9073                                    "Skipping, pinned stack task: " + tr);
9074                            continue;
9075                        }
9076                    }
9077                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9078                        // Don't include auto remove tasks that are finished or finishing.
9079                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9080                                "Skipping, auto-remove without activity: " + tr);
9081                        continue;
9082                    }
9083                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9084                            && !tr.isAvailable) {
9085                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9086                                "Skipping, unavail real act: " + tr);
9087                        continue;
9088                    }
9089
9090                    if (!tr.mUserSetupComplete) {
9091                        // Don't include task launched while user is not done setting-up.
9092                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9093                                "Skipping, user setup not complete: " + tr);
9094                        continue;
9095                    }
9096
9097                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9098                    if (!detailed) {
9099                        rti.baseIntent.replaceExtras((Bundle)null);
9100                    }
9101
9102                    res.add(rti);
9103                    maxNum--;
9104                }
9105            }
9106            return res;
9107        }
9108    }
9109
9110    @Override
9111    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9112        synchronized (this) {
9113            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9114                    "getTaskThumbnail()");
9115            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9116                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9117            if (tr != null) {
9118                return tr.getTaskThumbnailLocked();
9119            }
9120        }
9121        return null;
9122    }
9123
9124    @Override
9125    public int addAppTask(IBinder activityToken, Intent intent,
9126            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9127        final int callingUid = Binder.getCallingUid();
9128        final long callingIdent = Binder.clearCallingIdentity();
9129
9130        try {
9131            synchronized (this) {
9132                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9133                if (r == null) {
9134                    throw new IllegalArgumentException("Activity does not exist; token="
9135                            + activityToken);
9136                }
9137                ComponentName comp = intent.getComponent();
9138                if (comp == null) {
9139                    throw new IllegalArgumentException("Intent " + intent
9140                            + " must specify explicit component");
9141                }
9142                if (thumbnail.getWidth() != mThumbnailWidth
9143                        || thumbnail.getHeight() != mThumbnailHeight) {
9144                    throw new IllegalArgumentException("Bad thumbnail size: got "
9145                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9146                            + mThumbnailWidth + "x" + mThumbnailHeight);
9147                }
9148                if (intent.getSelector() != null) {
9149                    intent.setSelector(null);
9150                }
9151                if (intent.getSourceBounds() != null) {
9152                    intent.setSourceBounds(null);
9153                }
9154                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9155                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9156                        // The caller has added this as an auto-remove task...  that makes no
9157                        // sense, so turn off auto-remove.
9158                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9159                    }
9160                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
9161                    // Must be a new task.
9162                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9163                }
9164                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9165                    mLastAddedTaskActivity = null;
9166                }
9167                ActivityInfo ainfo = mLastAddedTaskActivity;
9168                if (ainfo == null) {
9169                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9170                            comp, 0, UserHandle.getUserId(callingUid));
9171                    if (ainfo.applicationInfo.uid != callingUid) {
9172                        throw new SecurityException(
9173                                "Can't add task for another application: target uid="
9174                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9175                    }
9176                }
9177
9178                // Use the full screen as the context for the task thumbnail
9179                final Point displaySize = new Point();
9180                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9181                r.task.stack.getDisplaySize(displaySize);
9182                thumbnailInfo.taskWidth = displaySize.x;
9183                thumbnailInfo.taskHeight = displaySize.y;
9184                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9185
9186                TaskRecord task = new TaskRecord(this,
9187                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9188                        ainfo, intent, description, thumbnailInfo);
9189
9190                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9191                if (trimIdx >= 0) {
9192                    // If this would have caused a trim, then we'll abort because that
9193                    // means it would be added at the end of the list but then just removed.
9194                    return INVALID_TASK_ID;
9195                }
9196
9197                final int N = mRecentTasks.size();
9198                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9199                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9200                    tr.removedFromRecents();
9201                }
9202
9203                task.inRecents = true;
9204                mRecentTasks.add(task);
9205                r.task.stack.addTask(task, false, "addAppTask");
9206
9207                task.setLastThumbnailLocked(thumbnail);
9208                task.freeLastThumbnail();
9209
9210                return task.taskId;
9211            }
9212        } finally {
9213            Binder.restoreCallingIdentity(callingIdent);
9214        }
9215    }
9216
9217    @Override
9218    public Point getAppTaskThumbnailSize() {
9219        synchronized (this) {
9220            return new Point(mThumbnailWidth,  mThumbnailHeight);
9221        }
9222    }
9223
9224    @Override
9225    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9226        synchronized (this) {
9227            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9228            if (r != null) {
9229                r.setTaskDescription(td);
9230                r.task.updateTaskDescription();
9231            }
9232        }
9233    }
9234
9235    @Override
9236    public void setTaskResizeable(int taskId, int resizeableMode) {
9237        synchronized (this) {
9238            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9239                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9240            if (task == null) {
9241                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9242                return;
9243            }
9244            if (task.mResizeMode != resizeableMode) {
9245                task.mResizeMode = resizeableMode;
9246                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9247                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9248                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9249            }
9250        }
9251    }
9252
9253    @Override
9254    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9255        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9256        long ident = Binder.clearCallingIdentity();
9257        try {
9258            synchronized (this) {
9259                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9260                if (task == null) {
9261                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9262                    return;
9263                }
9264                int stackId = task.stack.mStackId;
9265                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9266                // in crop windows resize mode or if the task size is affected by the docked stack
9267                // changing size. No need to update configuration.
9268                if (bounds != null && task.inCropWindowsResizeMode()
9269                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9270                    mWindowManager.scrollTask(task.taskId, bounds);
9271                    return;
9272                }
9273
9274                // Place the task in the right stack if it isn't there already based on
9275                // the requested bounds.
9276                // The stack transition logic is:
9277                // - a null bounds on a freeform task moves that task to fullscreen
9278                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9279                //   that task to freeform
9280                // - otherwise the task is not moved
9281                if (!StackId.isTaskResizeAllowed(stackId)) {
9282                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9283                }
9284                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9285                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9286                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9287                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9288                }
9289                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9290                if (stackId != task.stack.mStackId) {
9291                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9292                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9293                    preserveWindow = false;
9294                }
9295
9296                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9297                        false /* deferResume */);
9298            }
9299        } finally {
9300            Binder.restoreCallingIdentity(ident);
9301        }
9302    }
9303
9304    @Override
9305    public Rect getTaskBounds(int taskId) {
9306        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9307        long ident = Binder.clearCallingIdentity();
9308        Rect rect = new Rect();
9309        try {
9310            synchronized (this) {
9311                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9312                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9313                if (task == null) {
9314                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9315                    return rect;
9316                }
9317                if (task.stack != null) {
9318                    // Return the bounds from window manager since it will be adjusted for various
9319                    // things like the presense of a docked stack for tasks that aren't resizeable.
9320                    mWindowManager.getTaskBounds(task.taskId, rect);
9321                } else {
9322                    // Task isn't in window manager yet since it isn't associated with a stack.
9323                    // Return the persist value from activity manager
9324                    if (task.mBounds != null) {
9325                        rect.set(task.mBounds);
9326                    } else if (task.mLastNonFullscreenBounds != null) {
9327                        rect.set(task.mLastNonFullscreenBounds);
9328                    }
9329                }
9330            }
9331        } finally {
9332            Binder.restoreCallingIdentity(ident);
9333        }
9334        return rect;
9335    }
9336
9337    @Override
9338    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9339        if (userId != UserHandle.getCallingUserId()) {
9340            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9341                    "getTaskDescriptionIcon");
9342        }
9343        final File passedIconFile = new File(filePath);
9344        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9345                passedIconFile.getName());
9346        if (!legitIconFile.getPath().equals(filePath)
9347                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9348            throw new IllegalArgumentException("Bad file path: " + filePath
9349                    + " passed for userId " + userId);
9350        }
9351        return mRecentTasks.getTaskDescriptionIcon(filePath);
9352    }
9353
9354    @Override
9355    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9356            throws RemoteException {
9357        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9358                opts.getCustomInPlaceResId() == 0) {
9359            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9360                    "with valid animation");
9361        }
9362        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9363        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9364                opts.getCustomInPlaceResId());
9365        mWindowManager.executeAppTransition();
9366    }
9367
9368    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9369            boolean removeFromRecents) {
9370        if (removeFromRecents) {
9371            mRecentTasks.remove(tr);
9372            tr.removedFromRecents();
9373        }
9374        ComponentName component = tr.getBaseIntent().getComponent();
9375        if (component == null) {
9376            Slog.w(TAG, "No component for base intent of task: " + tr);
9377            return;
9378        }
9379
9380        // Find any running services associated with this app and stop if needed.
9381        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9382
9383        if (!killProcess) {
9384            return;
9385        }
9386
9387        // Determine if the process(es) for this task should be killed.
9388        final String pkg = component.getPackageName();
9389        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9390        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9391        for (int i = 0; i < pmap.size(); i++) {
9392
9393            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9394            for (int j = 0; j < uids.size(); j++) {
9395                ProcessRecord proc = uids.valueAt(j);
9396                if (proc.userId != tr.userId) {
9397                    // Don't kill process for a different user.
9398                    continue;
9399                }
9400                if (proc == mHomeProcess) {
9401                    // Don't kill the home process along with tasks from the same package.
9402                    continue;
9403                }
9404                if (!proc.pkgList.containsKey(pkg)) {
9405                    // Don't kill process that is not associated with this task.
9406                    continue;
9407                }
9408
9409                for (int k = 0; k < proc.activities.size(); k++) {
9410                    TaskRecord otherTask = proc.activities.get(k).task;
9411                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9412                        // Don't kill process(es) that has an activity in a different task that is
9413                        // also in recents.
9414                        return;
9415                    }
9416                }
9417
9418                if (proc.foregroundServices) {
9419                    // Don't kill process(es) with foreground service.
9420                    return;
9421                }
9422
9423                // Add process to kill list.
9424                procsToKill.add(proc);
9425            }
9426        }
9427
9428        // Kill the running processes.
9429        for (int i = 0; i < procsToKill.size(); i++) {
9430            ProcessRecord pr = procsToKill.get(i);
9431            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9432                    && pr.curReceiver == null) {
9433                pr.kill("remove task", true);
9434            } else {
9435                // We delay killing processes that are not in the background or running a receiver.
9436                pr.waitingToKill = "remove task";
9437            }
9438        }
9439    }
9440
9441    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9442        // Remove all tasks with activities in the specified package from the list of recent tasks
9443        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9444            TaskRecord tr = mRecentTasks.get(i);
9445            if (tr.userId != userId) continue;
9446
9447            ComponentName cn = tr.intent.getComponent();
9448            if (cn != null && cn.getPackageName().equals(packageName)) {
9449                // If the package name matches, remove the task.
9450                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9451            }
9452        }
9453    }
9454
9455    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9456            int userId) {
9457
9458        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9459            TaskRecord tr = mRecentTasks.get(i);
9460            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9461                continue;
9462            }
9463
9464            ComponentName cn = tr.intent.getComponent();
9465            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9466                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9467            if (sameComponent) {
9468                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9469            }
9470        }
9471    }
9472
9473    /**
9474     * Removes the task with the specified task id.
9475     *
9476     * @param taskId Identifier of the task to be removed.
9477     * @param killProcess Kill any process associated with the task if possible.
9478     * @param removeFromRecents Whether to also remove the task from recents.
9479     * @return Returns true if the given task was found and removed.
9480     */
9481    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9482            boolean removeFromRecents) {
9483        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9484                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9485        if (tr != null) {
9486            tr.removeTaskActivitiesLocked();
9487            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9488            if (tr.isPersistable) {
9489                notifyTaskPersisterLocked(null, true);
9490            }
9491            return true;
9492        }
9493        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9494        return false;
9495    }
9496
9497    @Override
9498    public void removeStack(int stackId) {
9499        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9500        if (stackId == HOME_STACK_ID) {
9501            throw new IllegalArgumentException("Removing home stack is not allowed.");
9502        }
9503
9504        synchronized (this) {
9505            final long ident = Binder.clearCallingIdentity();
9506            try {
9507                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9508                if (stack == null) {
9509                    return;
9510                }
9511                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9512                for (int i = tasks.size() - 1; i >= 0; i--) {
9513                    removeTaskByIdLocked(
9514                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9515                }
9516            } finally {
9517                Binder.restoreCallingIdentity(ident);
9518            }
9519        }
9520    }
9521
9522    @Override
9523    public boolean removeTask(int taskId) {
9524        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9525        synchronized (this) {
9526            final long ident = Binder.clearCallingIdentity();
9527            try {
9528                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9529            } finally {
9530                Binder.restoreCallingIdentity(ident);
9531            }
9532        }
9533    }
9534
9535    /**
9536     * TODO: Add mController hook
9537     */
9538    @Override
9539    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9540        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9541
9542        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9543        synchronized(this) {
9544            moveTaskToFrontLocked(taskId, flags, bOptions);
9545        }
9546    }
9547
9548    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9549        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9550
9551        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9552                Binder.getCallingUid(), -1, -1, "Task to front")) {
9553            ActivityOptions.abort(options);
9554            return;
9555        }
9556        final long origId = Binder.clearCallingIdentity();
9557        try {
9558            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9559            if (task == null) {
9560                Slog.d(TAG, "Could not find task for id: "+ taskId);
9561                return;
9562            }
9563            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9564                mStackSupervisor.showLockTaskToast();
9565                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9566                return;
9567            }
9568            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9569            if (prev != null && prev.isRecentsActivity()) {
9570                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9571            }
9572            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9573                    false /* forceNonResizable */);
9574        } finally {
9575            Binder.restoreCallingIdentity(origId);
9576        }
9577        ActivityOptions.abort(options);
9578    }
9579
9580    /**
9581     * Moves an activity, and all of the other activities within the same task, to the bottom
9582     * of the history stack.  The activity's order within the task is unchanged.
9583     *
9584     * @param token A reference to the activity we wish to move
9585     * @param nonRoot If false then this only works if the activity is the root
9586     *                of a task; if true it will work for any activity in a task.
9587     * @return Returns true if the move completed, false if not.
9588     */
9589    @Override
9590    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9591        enforceNotIsolatedCaller("moveActivityTaskToBack");
9592        synchronized(this) {
9593            final long origId = Binder.clearCallingIdentity();
9594            try {
9595                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9596                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9597                if (task != null) {
9598                    if (mStackSupervisor.isLockedTask(task)) {
9599                        mStackSupervisor.showLockTaskToast();
9600                        return false;
9601                    }
9602                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9603                }
9604            } finally {
9605                Binder.restoreCallingIdentity(origId);
9606            }
9607        }
9608        return false;
9609    }
9610
9611    @Override
9612    public void moveTaskBackwards(int task) {
9613        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9614                "moveTaskBackwards()");
9615
9616        synchronized(this) {
9617            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9618                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9619                return;
9620            }
9621            final long origId = Binder.clearCallingIdentity();
9622            moveTaskBackwardsLocked(task);
9623            Binder.restoreCallingIdentity(origId);
9624        }
9625    }
9626
9627    private final void moveTaskBackwardsLocked(int task) {
9628        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9629    }
9630
9631    @Override
9632    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9633            IActivityContainerCallback callback) throws RemoteException {
9634        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9635        synchronized (this) {
9636            if (parentActivityToken == null) {
9637                throw new IllegalArgumentException("parent token must not be null");
9638            }
9639            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9640            if (r == null) {
9641                return null;
9642            }
9643            if (callback == null) {
9644                throw new IllegalArgumentException("callback must not be null");
9645            }
9646            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9647        }
9648    }
9649
9650    @Override
9651    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9652        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9653        synchronized (this) {
9654            mStackSupervisor.deleteActivityContainer(container);
9655        }
9656    }
9657
9658    @Override
9659    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9660        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9661        synchronized (this) {
9662            final int stackId = mStackSupervisor.getNextStackId();
9663            final ActivityStack stack =
9664                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9665            if (stack == null) {
9666                return null;
9667            }
9668            return stack.mActivityContainer;
9669        }
9670    }
9671
9672    @Override
9673    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9674        synchronized (this) {
9675            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9676            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9677                return stack.mActivityContainer.getDisplayId();
9678            }
9679            return Display.DEFAULT_DISPLAY;
9680        }
9681    }
9682
9683    @Override
9684    public int getActivityStackId(IBinder token) throws RemoteException {
9685        synchronized (this) {
9686            ActivityStack stack = ActivityRecord.getStackLocked(token);
9687            if (stack == null) {
9688                return INVALID_STACK_ID;
9689            }
9690            return stack.mStackId;
9691        }
9692    }
9693
9694    @Override
9695    public void exitFreeformMode(IBinder token) throws RemoteException {
9696        synchronized (this) {
9697            long ident = Binder.clearCallingIdentity();
9698            try {
9699                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9700                if (r == null) {
9701                    throw new IllegalArgumentException(
9702                            "exitFreeformMode: No activity record matching token=" + token);
9703                }
9704                final ActivityStack stack = r.getStackLocked(token);
9705                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9706                    throw new IllegalStateException(
9707                            "exitFreeformMode: You can only go fullscreen from freeform.");
9708                }
9709                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9710                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9711                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9712            } finally {
9713                Binder.restoreCallingIdentity(ident);
9714            }
9715        }
9716    }
9717
9718    @Override
9719    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9720        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9721        if (stackId == HOME_STACK_ID) {
9722            throw new IllegalArgumentException(
9723                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9724        }
9725        synchronized (this) {
9726            long ident = Binder.clearCallingIdentity();
9727            try {
9728                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9729                        + " to stackId=" + stackId + " toTop=" + toTop);
9730                if (stackId == DOCKED_STACK_ID) {
9731                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9732                            null /* initialBounds */);
9733                }
9734                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9735                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9736                if (result && stackId == DOCKED_STACK_ID) {
9737                    // If task moved to docked stack - show recents if needed.
9738                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9739                            "moveTaskToDockedStack");
9740                }
9741            } finally {
9742                Binder.restoreCallingIdentity(ident);
9743            }
9744        }
9745    }
9746
9747    @Override
9748    public void swapDockedAndFullscreenStack() throws RemoteException {
9749        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9750        synchronized (this) {
9751            long ident = Binder.clearCallingIdentity();
9752            try {
9753                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9754                        FULLSCREEN_WORKSPACE_STACK_ID);
9755                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9756                        : null;
9757                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9758                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9759                        : null;
9760                if (topTask == null || tasks == null || tasks.size() == 0) {
9761                    Slog.w(TAG,
9762                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9763                    return;
9764                }
9765
9766                // TODO: App transition
9767                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9768
9769                // Defer the resume so resume/pausing while moving stacks is dangerous.
9770                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9771                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9772                        ANIMATE, true /* deferResume */);
9773                final int size = tasks.size();
9774                for (int i = 0; i < size; i++) {
9775                    final int id = tasks.get(i).taskId;
9776                    if (id == topTask.taskId) {
9777                        continue;
9778                    }
9779                    mStackSupervisor.moveTaskToStackLocked(id,
9780                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9781                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9782                }
9783
9784                // Because we deferred the resume, to avoid conflicts with stack switches while
9785                // resuming, we need to do it after all the tasks are moved.
9786                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9787                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9788
9789                mWindowManager.executeAppTransition();
9790            } finally {
9791                Binder.restoreCallingIdentity(ident);
9792            }
9793        }
9794    }
9795
9796    /**
9797     * Moves the input task to the docked stack.
9798     *
9799     * @param taskId Id of task to move.
9800     * @param createMode The mode the docked stack should be created in if it doesn't exist
9801     *                   already. See
9802     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9803     *                   and
9804     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9805     * @param toTop If the task and stack should be moved to the top.
9806     * @param animate Whether we should play an animation for the moving the task
9807     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9808     *                      docked stack. Pass {@code null} to use default bounds.
9809     */
9810    @Override
9811    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9812            Rect initialBounds, boolean moveHomeStackFront) {
9813        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9814        synchronized (this) {
9815            long ident = Binder.clearCallingIdentity();
9816            try {
9817                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9818                        + " to createMode=" + createMode + " toTop=" + toTop);
9819                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9820                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9821                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9822                        animate, DEFER_RESUME);
9823                if (moved) {
9824                    if (moveHomeStackFront) {
9825                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9826                    }
9827                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9828                }
9829                return moved;
9830            } finally {
9831                Binder.restoreCallingIdentity(ident);
9832            }
9833        }
9834    }
9835
9836    /**
9837     * Moves the top activity in the input stackId to the pinned stack.
9838     *
9839     * @param stackId Id of stack to move the top activity to pinned stack.
9840     * @param bounds Bounds to use for pinned stack.
9841     *
9842     * @return True if the top activity of the input stack was successfully moved to the pinned
9843     *          stack.
9844     */
9845    @Override
9846    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9847        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9848        synchronized (this) {
9849            if (!mSupportsPictureInPicture) {
9850                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9851                        + "Device doesn't support picture-in-pciture mode");
9852            }
9853
9854            long ident = Binder.clearCallingIdentity();
9855            try {
9856                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9857            } finally {
9858                Binder.restoreCallingIdentity(ident);
9859            }
9860        }
9861    }
9862
9863    @Override
9864    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9865            boolean preserveWindows, boolean animate, int animationDuration) {
9866        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9867        long ident = Binder.clearCallingIdentity();
9868        try {
9869            synchronized (this) {
9870                if (animate) {
9871                    if (stackId == PINNED_STACK_ID) {
9872                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9873                    } else {
9874                        throw new IllegalArgumentException("Stack: " + stackId
9875                                + " doesn't support animated resize.");
9876                    }
9877                } else {
9878                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9879                            null /* tempTaskInsetBounds */, preserveWindows,
9880                            allowResizeInDockedMode, !DEFER_RESUME);
9881                }
9882            }
9883        } finally {
9884            Binder.restoreCallingIdentity(ident);
9885        }
9886    }
9887
9888    @Override
9889    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9890            Rect tempDockedTaskInsetBounds,
9891            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9892        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9893                "resizeDockedStack()");
9894        long ident = Binder.clearCallingIdentity();
9895        try {
9896            synchronized (this) {
9897                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9898                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9899                        PRESERVE_WINDOWS);
9900            }
9901        } finally {
9902            Binder.restoreCallingIdentity(ident);
9903        }
9904    }
9905
9906    @Override
9907    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
9908        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9909                "resizePinnedStack()");
9910        final long ident = Binder.clearCallingIdentity();
9911        try {
9912            synchronized (this) {
9913                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
9914            }
9915        } finally {
9916            Binder.restoreCallingIdentity(ident);
9917        }
9918    }
9919
9920    @Override
9921    public void positionTaskInStack(int taskId, int stackId, int position) {
9922        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
9923        if (stackId == HOME_STACK_ID) {
9924            throw new IllegalArgumentException(
9925                    "positionTaskInStack: Attempt to change the position of task "
9926                    + taskId + " in/to home stack");
9927        }
9928        synchronized (this) {
9929            long ident = Binder.clearCallingIdentity();
9930            try {
9931                if (DEBUG_STACK) Slog.d(TAG_STACK,
9932                        "positionTaskInStack: positioning task=" + taskId
9933                        + " in stackId=" + stackId + " at position=" + position);
9934                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9935            } finally {
9936                Binder.restoreCallingIdentity(ident);
9937            }
9938        }
9939    }
9940
9941    @Override
9942    public List<StackInfo> getAllStackInfos() {
9943        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
9944        long ident = Binder.clearCallingIdentity();
9945        try {
9946            synchronized (this) {
9947                return mStackSupervisor.getAllStackInfosLocked();
9948            }
9949        } finally {
9950            Binder.restoreCallingIdentity(ident);
9951        }
9952    }
9953
9954    @Override
9955    public StackInfo getStackInfo(int stackId) {
9956        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9957        long ident = Binder.clearCallingIdentity();
9958        try {
9959            synchronized (this) {
9960                return mStackSupervisor.getStackInfoLocked(stackId);
9961            }
9962        } finally {
9963            Binder.restoreCallingIdentity(ident);
9964        }
9965    }
9966
9967    @Override
9968    public boolean isInHomeStack(int taskId) {
9969        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9970        long ident = Binder.clearCallingIdentity();
9971        try {
9972            synchronized (this) {
9973                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9974                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9975                return tr != null && tr.stack != null && tr.stack.isHomeStack();
9976            }
9977        } finally {
9978            Binder.restoreCallingIdentity(ident);
9979        }
9980    }
9981
9982    @Override
9983    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9984        synchronized(this) {
9985            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9986        }
9987    }
9988
9989    @Override
9990    public void updateDeviceOwner(String packageName) {
9991        final int callingUid = Binder.getCallingUid();
9992        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9993            throw new SecurityException("updateDeviceOwner called from non-system process");
9994        }
9995        synchronized (this) {
9996            mDeviceOwnerName = packageName;
9997        }
9998    }
9999
10000    @Override
10001    public void updateLockTaskPackages(int userId, String[] packages) {
10002        final int callingUid = Binder.getCallingUid();
10003        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10004            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10005                    "updateLockTaskPackages()");
10006        }
10007        synchronized (this) {
10008            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10009                    Arrays.toString(packages));
10010            mLockTaskPackages.put(userId, packages);
10011            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10012        }
10013    }
10014
10015
10016    void startLockTaskModeLocked(TaskRecord task) {
10017        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10018        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10019            return;
10020        }
10021
10022        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10023        // is initiated by system after the pinning request was shown and locked mode is initiated
10024        // by an authorized app directly
10025        final int callingUid = Binder.getCallingUid();
10026        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10027        long ident = Binder.clearCallingIdentity();
10028        try {
10029            if (!isSystemInitiated) {
10030                task.mLockTaskUid = callingUid;
10031                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10032                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10033                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10034                    StatusBarManagerInternal statusBarManager =
10035                            LocalServices.getService(StatusBarManagerInternal.class);
10036                    if (statusBarManager != null) {
10037                        statusBarManager.showScreenPinningRequest(task.taskId);
10038                    }
10039                    return;
10040                }
10041
10042                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10043                if (stack == null || task != stack.topTask()) {
10044                    throw new IllegalArgumentException("Invalid task, not in foreground");
10045                }
10046            }
10047            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10048                    "Locking fully");
10049            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10050                    ActivityManager.LOCK_TASK_MODE_PINNED :
10051                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10052                    "startLockTask", true);
10053        } finally {
10054            Binder.restoreCallingIdentity(ident);
10055        }
10056    }
10057
10058    @Override
10059    public void startLockTaskMode(int taskId) {
10060        synchronized (this) {
10061            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10062            if (task != null) {
10063                startLockTaskModeLocked(task);
10064            }
10065        }
10066    }
10067
10068    @Override
10069    public void startLockTaskMode(IBinder token) {
10070        synchronized (this) {
10071            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10072            if (r == null) {
10073                return;
10074            }
10075            final TaskRecord task = r.task;
10076            if (task != null) {
10077                startLockTaskModeLocked(task);
10078            }
10079        }
10080    }
10081
10082    @Override
10083    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10084        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10085        // This makes inner call to look as if it was initiated by system.
10086        long ident = Binder.clearCallingIdentity();
10087        try {
10088            synchronized (this) {
10089                startLockTaskMode(taskId);
10090            }
10091        } finally {
10092            Binder.restoreCallingIdentity(ident);
10093        }
10094    }
10095
10096    @Override
10097    public void stopLockTaskMode() {
10098        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10099        if (lockTask == null) {
10100            // Our work here is done.
10101            return;
10102        }
10103
10104        final int callingUid = Binder.getCallingUid();
10105        final int lockTaskUid = lockTask.mLockTaskUid;
10106        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10107        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10108            // Done.
10109            return;
10110        } else {
10111            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10112            // It is possible lockTaskMode was started by the system process because
10113            // android:lockTaskMode is set to a locking value in the application manifest
10114            // instead of the app calling startLockTaskMode. In this case
10115            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10116            // {@link TaskRecord.effectiveUid} instead. Also caller with
10117            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10118            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10119                    && callingUid != lockTaskUid
10120                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10121                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10122                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10123            }
10124        }
10125        long ident = Binder.clearCallingIdentity();
10126        try {
10127            Log.d(TAG, "stopLockTaskMode");
10128            // Stop lock task
10129            synchronized (this) {
10130                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10131                        "stopLockTask", true);
10132            }
10133            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10134            if (tm != null) {
10135                tm.showInCallScreen(false);
10136            }
10137        } finally {
10138            Binder.restoreCallingIdentity(ident);
10139        }
10140    }
10141
10142    /**
10143     * This API should be called by SystemUI only when user perform certain action to dismiss
10144     * lock task mode. We should only dismiss pinned lock task mode in this case.
10145     */
10146    @Override
10147    public void stopSystemLockTaskMode() throws RemoteException {
10148        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10149            stopLockTaskMode();
10150        } else {
10151            mStackSupervisor.showLockTaskToast();
10152        }
10153    }
10154
10155    @Override
10156    public boolean isInLockTaskMode() {
10157        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10158    }
10159
10160    @Override
10161    public int getLockTaskModeState() {
10162        synchronized (this) {
10163            return mStackSupervisor.getLockTaskModeState();
10164        }
10165    }
10166
10167    @Override
10168    public void showLockTaskEscapeMessage(IBinder token) {
10169        synchronized (this) {
10170            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10171            if (r == null) {
10172                return;
10173            }
10174            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10175        }
10176    }
10177
10178    // =========================================================
10179    // CONTENT PROVIDERS
10180    // =========================================================
10181
10182    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10183        List<ProviderInfo> providers = null;
10184        try {
10185            providers = AppGlobals.getPackageManager()
10186                    .queryContentProviders(app.processName, app.uid,
10187                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10188                                    | MATCH_DEBUG_TRIAGED_MISSING)
10189                    .getList();
10190        } catch (RemoteException ex) {
10191        }
10192        if (DEBUG_MU) Slog.v(TAG_MU,
10193                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10194        int userId = app.userId;
10195        if (providers != null) {
10196            int N = providers.size();
10197            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10198            for (int i=0; i<N; i++) {
10199                // TODO: keep logic in sync with installEncryptionUnawareProviders
10200                ProviderInfo cpi =
10201                    (ProviderInfo)providers.get(i);
10202                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10203                        cpi.name, cpi.flags);
10204                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10205                    // This is a singleton provider, but a user besides the
10206                    // default user is asking to initialize a process it runs
10207                    // in...  well, no, it doesn't actually run in this process,
10208                    // it runs in the process of the default user.  Get rid of it.
10209                    providers.remove(i);
10210                    N--;
10211                    i--;
10212                    continue;
10213                }
10214
10215                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10216                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10217                if (cpr == null) {
10218                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10219                    mProviderMap.putProviderByClass(comp, cpr);
10220                }
10221                if (DEBUG_MU) Slog.v(TAG_MU,
10222                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10223                app.pubProviders.put(cpi.name, cpr);
10224                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10225                    // Don't add this if it is a platform component that is marked
10226                    // to run in multiple processes, because this is actually
10227                    // part of the framework so doesn't make sense to track as a
10228                    // separate apk in the process.
10229                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10230                            mProcessStats);
10231                }
10232                notifyPackageUse(cpi.applicationInfo.packageName,
10233                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10234            }
10235        }
10236        return providers;
10237    }
10238
10239    /**
10240     * Check if {@link ProcessRecord} has a possible chance at accessing the
10241     * given {@link ProviderInfo}. Final permission checking is always done
10242     * in {@link ContentProvider}.
10243     */
10244    private final String checkContentProviderPermissionLocked(
10245            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10246        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10247        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10248        boolean checkedGrants = false;
10249        if (checkUser) {
10250            // Looking for cross-user grants before enforcing the typical cross-users permissions
10251            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10252            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10253                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10254                    return null;
10255                }
10256                checkedGrants = true;
10257            }
10258            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10259                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10260            if (userId != tmpTargetUserId) {
10261                // When we actually went to determine the final targer user ID, this ended
10262                // up different than our initial check for the authority.  This is because
10263                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10264                // SELF.  So we need to re-check the grants again.
10265                checkedGrants = false;
10266            }
10267        }
10268        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10269                cpi.applicationInfo.uid, cpi.exported)
10270                == PackageManager.PERMISSION_GRANTED) {
10271            return null;
10272        }
10273        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10274                cpi.applicationInfo.uid, cpi.exported)
10275                == PackageManager.PERMISSION_GRANTED) {
10276            return null;
10277        }
10278
10279        PathPermission[] pps = cpi.pathPermissions;
10280        if (pps != null) {
10281            int i = pps.length;
10282            while (i > 0) {
10283                i--;
10284                PathPermission pp = pps[i];
10285                String pprperm = pp.getReadPermission();
10286                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10287                        cpi.applicationInfo.uid, cpi.exported)
10288                        == PackageManager.PERMISSION_GRANTED) {
10289                    return null;
10290                }
10291                String ppwperm = pp.getWritePermission();
10292                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10293                        cpi.applicationInfo.uid, cpi.exported)
10294                        == PackageManager.PERMISSION_GRANTED) {
10295                    return null;
10296                }
10297            }
10298        }
10299        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10300            return null;
10301        }
10302
10303        String msg;
10304        if (!cpi.exported) {
10305            msg = "Permission Denial: opening provider " + cpi.name
10306                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10307                    + ", uid=" + callingUid + ") that is not exported from uid "
10308                    + cpi.applicationInfo.uid;
10309        } else {
10310            msg = "Permission Denial: opening provider " + cpi.name
10311                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10312                    + ", uid=" + callingUid + ") requires "
10313                    + cpi.readPermission + " or " + cpi.writePermission;
10314        }
10315        Slog.w(TAG, msg);
10316        return msg;
10317    }
10318
10319    /**
10320     * Returns if the ContentProvider has granted a uri to callingUid
10321     */
10322    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10323        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10324        if (perms != null) {
10325            for (int i=perms.size()-1; i>=0; i--) {
10326                GrantUri grantUri = perms.keyAt(i);
10327                if (grantUri.sourceUserId == userId || !checkUser) {
10328                    if (matchesProvider(grantUri.uri, cpi)) {
10329                        return true;
10330                    }
10331                }
10332            }
10333        }
10334        return false;
10335    }
10336
10337    /**
10338     * Returns true if the uri authority is one of the authorities specified in the provider.
10339     */
10340    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10341        String uriAuth = uri.getAuthority();
10342        String cpiAuth = cpi.authority;
10343        if (cpiAuth.indexOf(';') == -1) {
10344            return cpiAuth.equals(uriAuth);
10345        }
10346        String[] cpiAuths = cpiAuth.split(";");
10347        int length = cpiAuths.length;
10348        for (int i = 0; i < length; i++) {
10349            if (cpiAuths[i].equals(uriAuth)) return true;
10350        }
10351        return false;
10352    }
10353
10354    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10355            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10356        if (r != null) {
10357            for (int i=0; i<r.conProviders.size(); i++) {
10358                ContentProviderConnection conn = r.conProviders.get(i);
10359                if (conn.provider == cpr) {
10360                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10361                            "Adding provider requested by "
10362                            + r.processName + " from process "
10363                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10364                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10365                    if (stable) {
10366                        conn.stableCount++;
10367                        conn.numStableIncs++;
10368                    } else {
10369                        conn.unstableCount++;
10370                        conn.numUnstableIncs++;
10371                    }
10372                    return conn;
10373                }
10374            }
10375            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10376            if (stable) {
10377                conn.stableCount = 1;
10378                conn.numStableIncs = 1;
10379            } else {
10380                conn.unstableCount = 1;
10381                conn.numUnstableIncs = 1;
10382            }
10383            cpr.connections.add(conn);
10384            r.conProviders.add(conn);
10385            startAssociationLocked(r.uid, r.processName, r.curProcState,
10386                    cpr.uid, cpr.name, cpr.info.processName);
10387            return conn;
10388        }
10389        cpr.addExternalProcessHandleLocked(externalProcessToken);
10390        return null;
10391    }
10392
10393    boolean decProviderCountLocked(ContentProviderConnection conn,
10394            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10395        if (conn != null) {
10396            cpr = conn.provider;
10397            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10398                    "Removing provider requested by "
10399                    + conn.client.processName + " from process "
10400                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10401                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10402            if (stable) {
10403                conn.stableCount--;
10404            } else {
10405                conn.unstableCount--;
10406            }
10407            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10408                cpr.connections.remove(conn);
10409                conn.client.conProviders.remove(conn);
10410                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10411                    // The client is more important than last activity -- note the time this
10412                    // is happening, so we keep the old provider process around a bit as last
10413                    // activity to avoid thrashing it.
10414                    if (cpr.proc != null) {
10415                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10416                    }
10417                }
10418                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10419                return true;
10420            }
10421            return false;
10422        }
10423        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10424        return false;
10425    }
10426
10427    private void checkTime(long startTime, String where) {
10428        long now = SystemClock.uptimeMillis();
10429        if ((now-startTime) > 50) {
10430            // If we are taking more than 50ms, log about it.
10431            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10432        }
10433    }
10434
10435    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10436            String name, IBinder token, boolean stable, int userId) {
10437        ContentProviderRecord cpr;
10438        ContentProviderConnection conn = null;
10439        ProviderInfo cpi = null;
10440
10441        synchronized(this) {
10442            long startTime = SystemClock.uptimeMillis();
10443
10444            ProcessRecord r = null;
10445            if (caller != null) {
10446                r = getRecordForAppLocked(caller);
10447                if (r == null) {
10448                    throw new SecurityException(
10449                            "Unable to find app for caller " + caller
10450                          + " (pid=" + Binder.getCallingPid()
10451                          + ") when getting content provider " + name);
10452                }
10453            }
10454
10455            boolean checkCrossUser = true;
10456
10457            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10458
10459            // First check if this content provider has been published...
10460            cpr = mProviderMap.getProviderByName(name, userId);
10461            // If that didn't work, check if it exists for user 0 and then
10462            // verify that it's a singleton provider before using it.
10463            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10464                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10465                if (cpr != null) {
10466                    cpi = cpr.info;
10467                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10468                            cpi.name, cpi.flags)
10469                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10470                        userId = UserHandle.USER_SYSTEM;
10471                        checkCrossUser = false;
10472                    } else {
10473                        cpr = null;
10474                        cpi = null;
10475                    }
10476                }
10477            }
10478
10479            boolean providerRunning = cpr != null;
10480            if (providerRunning) {
10481                cpi = cpr.info;
10482                String msg;
10483                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10484                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10485                        != null) {
10486                    throw new SecurityException(msg);
10487                }
10488                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10489
10490                if (r != null && cpr.canRunHere(r)) {
10491                    // This provider has been published or is in the process
10492                    // of being published...  but it is also allowed to run
10493                    // in the caller's process, so don't make a connection
10494                    // and just let the caller instantiate its own instance.
10495                    ContentProviderHolder holder = cpr.newHolder(null);
10496                    // don't give caller the provider object, it needs
10497                    // to make its own.
10498                    holder.provider = null;
10499                    return holder;
10500                }
10501
10502                final long origId = Binder.clearCallingIdentity();
10503
10504                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10505
10506                // In this case the provider instance already exists, so we can
10507                // return it right away.
10508                conn = incProviderCountLocked(r, cpr, token, stable);
10509                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10510                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10511                        // If this is a perceptible app accessing the provider,
10512                        // make sure to count it as being accessed and thus
10513                        // back up on the LRU list.  This is good because
10514                        // content providers are often expensive to start.
10515                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10516                        updateLruProcessLocked(cpr.proc, false, null);
10517                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10518                    }
10519                }
10520
10521                if (cpr.proc != null) {
10522                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10523                    boolean success = updateOomAdjLocked(cpr.proc);
10524                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10525                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10526                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10527                    // NOTE: there is still a race here where a signal could be
10528                    // pending on the process even though we managed to update its
10529                    // adj level.  Not sure what to do about this, but at least
10530                    // the race is now smaller.
10531                    if (!success) {
10532                        // Uh oh...  it looks like the provider's process
10533                        // has been killed on us.  We need to wait for a new
10534                        // process to be started, and make sure its death
10535                        // doesn't kill our process.
10536                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10537                                + " is crashing; detaching " + r);
10538                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10539                        checkTime(startTime, "getContentProviderImpl: before appDied");
10540                        appDiedLocked(cpr.proc);
10541                        checkTime(startTime, "getContentProviderImpl: after appDied");
10542                        if (!lastRef) {
10543                            // This wasn't the last ref our process had on
10544                            // the provider...  we have now been killed, bail.
10545                            return null;
10546                        }
10547                        providerRunning = false;
10548                        conn = null;
10549                    }
10550                }
10551
10552                Binder.restoreCallingIdentity(origId);
10553            }
10554
10555            if (!providerRunning) {
10556                try {
10557                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10558                    cpi = AppGlobals.getPackageManager().
10559                        resolveContentProvider(name,
10560                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10561                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10562                } catch (RemoteException ex) {
10563                }
10564                if (cpi == null) {
10565                    return null;
10566                }
10567                // If the provider is a singleton AND
10568                // (it's a call within the same user || the provider is a
10569                // privileged app)
10570                // Then allow connecting to the singleton provider
10571                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10572                        cpi.name, cpi.flags)
10573                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10574                if (singleton) {
10575                    userId = UserHandle.USER_SYSTEM;
10576                }
10577                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10578                checkTime(startTime, "getContentProviderImpl: got app info for user");
10579
10580                String msg;
10581                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10582                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10583                        != null) {
10584                    throw new SecurityException(msg);
10585                }
10586                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10587
10588                if (!mProcessesReady
10589                        && !cpi.processName.equals("system")) {
10590                    // If this content provider does not run in the system
10591                    // process, and the system is not yet ready to run other
10592                    // processes, then fail fast instead of hanging.
10593                    throw new IllegalArgumentException(
10594                            "Attempt to launch content provider before system ready");
10595                }
10596
10597                // Make sure that the user who owns this provider is running.  If not,
10598                // we don't want to allow it to run.
10599                if (!mUserController.isUserRunningLocked(userId, 0)) {
10600                    Slog.w(TAG, "Unable to launch app "
10601                            + cpi.applicationInfo.packageName + "/"
10602                            + cpi.applicationInfo.uid + " for provider "
10603                            + name + ": user " + userId + " is stopped");
10604                    return null;
10605                }
10606
10607                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10608                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10609                cpr = mProviderMap.getProviderByClass(comp, userId);
10610                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10611                final boolean firstClass = cpr == null;
10612                if (firstClass) {
10613                    final long ident = Binder.clearCallingIdentity();
10614
10615                    // If permissions need a review before any of the app components can run,
10616                    // we return no provider and launch a review activity if the calling app
10617                    // is in the foreground.
10618                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10619                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10620                            return null;
10621                        }
10622                    }
10623
10624                    try {
10625                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10626                        ApplicationInfo ai =
10627                            AppGlobals.getPackageManager().
10628                                getApplicationInfo(
10629                                        cpi.applicationInfo.packageName,
10630                                        STOCK_PM_FLAGS, userId);
10631                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10632                        if (ai == null) {
10633                            Slog.w(TAG, "No package info for content provider "
10634                                    + cpi.name);
10635                            return null;
10636                        }
10637                        ai = getAppInfoForUser(ai, userId);
10638                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10639                    } catch (RemoteException ex) {
10640                        // pm is in same process, this will never happen.
10641                    } finally {
10642                        Binder.restoreCallingIdentity(ident);
10643                    }
10644                }
10645
10646                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10647
10648                if (r != null && cpr.canRunHere(r)) {
10649                    // If this is a multiprocess provider, then just return its
10650                    // info and allow the caller to instantiate it.  Only do
10651                    // this if the provider is the same user as the caller's
10652                    // process, or can run as root (so can be in any process).
10653                    return cpr.newHolder(null);
10654                }
10655
10656                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10657                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10658                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10659
10660                // This is single process, and our app is now connecting to it.
10661                // See if we are already in the process of launching this
10662                // provider.
10663                final int N = mLaunchingProviders.size();
10664                int i;
10665                for (i = 0; i < N; i++) {
10666                    if (mLaunchingProviders.get(i) == cpr) {
10667                        break;
10668                    }
10669                }
10670
10671                // If the provider is not already being launched, then get it
10672                // started.
10673                if (i >= N) {
10674                    final long origId = Binder.clearCallingIdentity();
10675
10676                    try {
10677                        // Content provider is now in use, its package can't be stopped.
10678                        try {
10679                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10680                            AppGlobals.getPackageManager().setPackageStoppedState(
10681                                    cpr.appInfo.packageName, false, userId);
10682                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10683                        } catch (RemoteException e) {
10684                        } catch (IllegalArgumentException e) {
10685                            Slog.w(TAG, "Failed trying to unstop package "
10686                                    + cpr.appInfo.packageName + ": " + e);
10687                        }
10688
10689                        // Use existing process if already started
10690                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10691                        ProcessRecord proc = getProcessRecordLocked(
10692                                cpi.processName, cpr.appInfo.uid, false);
10693                        if (proc != null && proc.thread != null) {
10694                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10695                                    "Installing in existing process " + proc);
10696                            if (!proc.pubProviders.containsKey(cpi.name)) {
10697                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10698                                proc.pubProviders.put(cpi.name, cpr);
10699                                try {
10700                                    proc.thread.scheduleInstallProvider(cpi);
10701                                } catch (RemoteException e) {
10702                                }
10703                            }
10704                        } else {
10705                            checkTime(startTime, "getContentProviderImpl: before start process");
10706                            proc = startProcessLocked(cpi.processName,
10707                                    cpr.appInfo, false, 0, "content provider",
10708                                    new ComponentName(cpi.applicationInfo.packageName,
10709                                            cpi.name), false, false, false);
10710                            checkTime(startTime, "getContentProviderImpl: after start process");
10711                            if (proc == null) {
10712                                Slog.w(TAG, "Unable to launch app "
10713                                        + cpi.applicationInfo.packageName + "/"
10714                                        + cpi.applicationInfo.uid + " for provider "
10715                                        + name + ": process is bad");
10716                                return null;
10717                            }
10718                        }
10719                        cpr.launchingApp = proc;
10720                        mLaunchingProviders.add(cpr);
10721                    } finally {
10722                        Binder.restoreCallingIdentity(origId);
10723                    }
10724                }
10725
10726                checkTime(startTime, "getContentProviderImpl: updating data structures");
10727
10728                // Make sure the provider is published (the same provider class
10729                // may be published under multiple names).
10730                if (firstClass) {
10731                    mProviderMap.putProviderByClass(comp, cpr);
10732                }
10733
10734                mProviderMap.putProviderByName(name, cpr);
10735                conn = incProviderCountLocked(r, cpr, token, stable);
10736                if (conn != null) {
10737                    conn.waiting = true;
10738                }
10739            }
10740            checkTime(startTime, "getContentProviderImpl: done!");
10741        }
10742
10743        // Wait for the provider to be published...
10744        synchronized (cpr) {
10745            while (cpr.provider == null) {
10746                if (cpr.launchingApp == null) {
10747                    Slog.w(TAG, "Unable to launch app "
10748                            + cpi.applicationInfo.packageName + "/"
10749                            + cpi.applicationInfo.uid + " for provider "
10750                            + name + ": launching app became null");
10751                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10752                            UserHandle.getUserId(cpi.applicationInfo.uid),
10753                            cpi.applicationInfo.packageName,
10754                            cpi.applicationInfo.uid, name);
10755                    return null;
10756                }
10757                try {
10758                    if (DEBUG_MU) Slog.v(TAG_MU,
10759                            "Waiting to start provider " + cpr
10760                            + " launchingApp=" + cpr.launchingApp);
10761                    if (conn != null) {
10762                        conn.waiting = true;
10763                    }
10764                    cpr.wait();
10765                } catch (InterruptedException ex) {
10766                } finally {
10767                    if (conn != null) {
10768                        conn.waiting = false;
10769                    }
10770                }
10771            }
10772        }
10773        return cpr != null ? cpr.newHolder(conn) : null;
10774    }
10775
10776    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10777            ProcessRecord r, final int userId) {
10778        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10779                cpi.packageName, userId)) {
10780
10781            final boolean callerForeground = r == null || r.setSchedGroup
10782                    != ProcessList.SCHED_GROUP_BACKGROUND;
10783
10784            // Show a permission review UI only for starting from a foreground app
10785            if (!callerForeground) {
10786                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10787                        + cpi.packageName + " requires a permissions review");
10788                return false;
10789            }
10790
10791            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10792            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10793                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10794            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10795
10796            if (DEBUG_PERMISSIONS_REVIEW) {
10797                Slog.i(TAG, "u" + userId + " Launching permission review "
10798                        + "for package " + cpi.packageName);
10799            }
10800
10801            final UserHandle userHandle = new UserHandle(userId);
10802            mHandler.post(new Runnable() {
10803                @Override
10804                public void run() {
10805                    mContext.startActivityAsUser(intent, userHandle);
10806                }
10807            });
10808
10809            return false;
10810        }
10811
10812        return true;
10813    }
10814
10815    PackageManagerInternal getPackageManagerInternalLocked() {
10816        if (mPackageManagerInt == null) {
10817            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10818        }
10819        return mPackageManagerInt;
10820    }
10821
10822    @Override
10823    public final ContentProviderHolder getContentProvider(
10824            IApplicationThread caller, String name, int userId, boolean stable) {
10825        enforceNotIsolatedCaller("getContentProvider");
10826        if (caller == null) {
10827            String msg = "null IApplicationThread when getting content provider "
10828                    + name;
10829            Slog.w(TAG, msg);
10830            throw new SecurityException(msg);
10831        }
10832        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10833        // with cross-user grant.
10834        return getContentProviderImpl(caller, name, null, stable, userId);
10835    }
10836
10837    public ContentProviderHolder getContentProviderExternal(
10838            String name, int userId, IBinder token) {
10839        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10840            "Do not have permission in call getContentProviderExternal()");
10841        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10842                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10843        return getContentProviderExternalUnchecked(name, token, userId);
10844    }
10845
10846    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10847            IBinder token, int userId) {
10848        return getContentProviderImpl(null, name, token, true, userId);
10849    }
10850
10851    /**
10852     * Drop a content provider from a ProcessRecord's bookkeeping
10853     */
10854    public void removeContentProvider(IBinder connection, boolean stable) {
10855        enforceNotIsolatedCaller("removeContentProvider");
10856        long ident = Binder.clearCallingIdentity();
10857        try {
10858            synchronized (this) {
10859                ContentProviderConnection conn;
10860                try {
10861                    conn = (ContentProviderConnection)connection;
10862                } catch (ClassCastException e) {
10863                    String msg ="removeContentProvider: " + connection
10864                            + " not a ContentProviderConnection";
10865                    Slog.w(TAG, msg);
10866                    throw new IllegalArgumentException(msg);
10867                }
10868                if (conn == null) {
10869                    throw new NullPointerException("connection is null");
10870                }
10871                if (decProviderCountLocked(conn, null, null, stable)) {
10872                    updateOomAdjLocked();
10873                }
10874            }
10875        } finally {
10876            Binder.restoreCallingIdentity(ident);
10877        }
10878    }
10879
10880    public void removeContentProviderExternal(String name, IBinder token) {
10881        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10882            "Do not have permission in call removeContentProviderExternal()");
10883        int userId = UserHandle.getCallingUserId();
10884        long ident = Binder.clearCallingIdentity();
10885        try {
10886            removeContentProviderExternalUnchecked(name, token, userId);
10887        } finally {
10888            Binder.restoreCallingIdentity(ident);
10889        }
10890    }
10891
10892    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10893        synchronized (this) {
10894            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10895            if(cpr == null) {
10896                //remove from mProvidersByClass
10897                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10898                return;
10899            }
10900
10901            //update content provider record entry info
10902            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10903            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10904            if (localCpr.hasExternalProcessHandles()) {
10905                if (localCpr.removeExternalProcessHandleLocked(token)) {
10906                    updateOomAdjLocked();
10907                } else {
10908                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10909                            + " with no external reference for token: "
10910                            + token + ".");
10911                }
10912            } else {
10913                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10914                        + " with no external references.");
10915            }
10916        }
10917    }
10918
10919    public final void publishContentProviders(IApplicationThread caller,
10920            List<ContentProviderHolder> providers) {
10921        if (providers == null) {
10922            return;
10923        }
10924
10925        enforceNotIsolatedCaller("publishContentProviders");
10926        synchronized (this) {
10927            final ProcessRecord r = getRecordForAppLocked(caller);
10928            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10929            if (r == null) {
10930                throw new SecurityException(
10931                        "Unable to find app for caller " + caller
10932                      + " (pid=" + Binder.getCallingPid()
10933                      + ") when publishing content providers");
10934            }
10935
10936            final long origId = Binder.clearCallingIdentity();
10937
10938            final int N = providers.size();
10939            for (int i = 0; i < N; i++) {
10940                ContentProviderHolder src = providers.get(i);
10941                if (src == null || src.info == null || src.provider == null) {
10942                    continue;
10943                }
10944                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10945                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10946                if (dst != null) {
10947                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10948                    mProviderMap.putProviderByClass(comp, dst);
10949                    String names[] = dst.info.authority.split(";");
10950                    for (int j = 0; j < names.length; j++) {
10951                        mProviderMap.putProviderByName(names[j], dst);
10952                    }
10953
10954                    int launchingCount = mLaunchingProviders.size();
10955                    int j;
10956                    boolean wasInLaunchingProviders = false;
10957                    for (j = 0; j < launchingCount; j++) {
10958                        if (mLaunchingProviders.get(j) == dst) {
10959                            mLaunchingProviders.remove(j);
10960                            wasInLaunchingProviders = true;
10961                            j--;
10962                            launchingCount--;
10963                        }
10964                    }
10965                    if (wasInLaunchingProviders) {
10966                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
10967                    }
10968                    synchronized (dst) {
10969                        dst.provider = src.provider;
10970                        dst.proc = r;
10971                        dst.notifyAll();
10972                    }
10973                    updateOomAdjLocked(r);
10974                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
10975                            src.info.authority);
10976                }
10977            }
10978
10979            Binder.restoreCallingIdentity(origId);
10980        }
10981    }
10982
10983    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
10984        ContentProviderConnection conn;
10985        try {
10986            conn = (ContentProviderConnection)connection;
10987        } catch (ClassCastException e) {
10988            String msg ="refContentProvider: " + connection
10989                    + " not a ContentProviderConnection";
10990            Slog.w(TAG, msg);
10991            throw new IllegalArgumentException(msg);
10992        }
10993        if (conn == null) {
10994            throw new NullPointerException("connection is null");
10995        }
10996
10997        synchronized (this) {
10998            if (stable > 0) {
10999                conn.numStableIncs += stable;
11000            }
11001            stable = conn.stableCount + stable;
11002            if (stable < 0) {
11003                throw new IllegalStateException("stableCount < 0: " + stable);
11004            }
11005
11006            if (unstable > 0) {
11007                conn.numUnstableIncs += unstable;
11008            }
11009            unstable = conn.unstableCount + unstable;
11010            if (unstable < 0) {
11011                throw new IllegalStateException("unstableCount < 0: " + unstable);
11012            }
11013
11014            if ((stable+unstable) <= 0) {
11015                throw new IllegalStateException("ref counts can't go to zero here: stable="
11016                        + stable + " unstable=" + unstable);
11017            }
11018            conn.stableCount = stable;
11019            conn.unstableCount = unstable;
11020            return !conn.dead;
11021        }
11022    }
11023
11024    public void unstableProviderDied(IBinder connection) {
11025        ContentProviderConnection conn;
11026        try {
11027            conn = (ContentProviderConnection)connection;
11028        } catch (ClassCastException e) {
11029            String msg ="refContentProvider: " + connection
11030                    + " not a ContentProviderConnection";
11031            Slog.w(TAG, msg);
11032            throw new IllegalArgumentException(msg);
11033        }
11034        if (conn == null) {
11035            throw new NullPointerException("connection is null");
11036        }
11037
11038        // Safely retrieve the content provider associated with the connection.
11039        IContentProvider provider;
11040        synchronized (this) {
11041            provider = conn.provider.provider;
11042        }
11043
11044        if (provider == null) {
11045            // Um, yeah, we're way ahead of you.
11046            return;
11047        }
11048
11049        // Make sure the caller is being honest with us.
11050        if (provider.asBinder().pingBinder()) {
11051            // Er, no, still looks good to us.
11052            synchronized (this) {
11053                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11054                        + " says " + conn + " died, but we don't agree");
11055                return;
11056            }
11057        }
11058
11059        // Well look at that!  It's dead!
11060        synchronized (this) {
11061            if (conn.provider.provider != provider) {
11062                // But something changed...  good enough.
11063                return;
11064            }
11065
11066            ProcessRecord proc = conn.provider.proc;
11067            if (proc == null || proc.thread == null) {
11068                // Seems like the process is already cleaned up.
11069                return;
11070            }
11071
11072            // As far as we're concerned, this is just like receiving a
11073            // death notification...  just a bit prematurely.
11074            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11075                    + ") early provider death");
11076            final long ident = Binder.clearCallingIdentity();
11077            try {
11078                appDiedLocked(proc);
11079            } finally {
11080                Binder.restoreCallingIdentity(ident);
11081            }
11082        }
11083    }
11084
11085    @Override
11086    public void appNotRespondingViaProvider(IBinder connection) {
11087        enforceCallingPermission(
11088                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11089
11090        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11091        if (conn == null) {
11092            Slog.w(TAG, "ContentProviderConnection is null");
11093            return;
11094        }
11095
11096        final ProcessRecord host = conn.provider.proc;
11097        if (host == null) {
11098            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11099            return;
11100        }
11101
11102        mHandler.post(new Runnable() {
11103            @Override
11104            public void run() {
11105                mAppErrors.appNotResponding(host, null, null, false,
11106                        "ContentProvider not responding");
11107            }
11108        });
11109    }
11110
11111    public final void installSystemProviders() {
11112        List<ProviderInfo> providers;
11113        synchronized (this) {
11114            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11115            providers = generateApplicationProvidersLocked(app);
11116            if (providers != null) {
11117                for (int i=providers.size()-1; i>=0; i--) {
11118                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11119                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11120                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11121                                + ": not system .apk");
11122                        providers.remove(i);
11123                    }
11124                }
11125            }
11126        }
11127        if (providers != null) {
11128            mSystemThread.installSystemProviders(providers);
11129        }
11130
11131        mCoreSettingsObserver = new CoreSettingsObserver(this);
11132        mFontScaleSettingObserver = new FontScaleSettingObserver();
11133
11134        //mUsageStatsService.monitorPackages();
11135    }
11136
11137    private void startPersistentApps(int matchFlags) {
11138        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11139
11140        synchronized (this) {
11141            try {
11142                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11143                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11144                for (ApplicationInfo app : apps) {
11145                    if (!"android".equals(app.packageName)) {
11146                        addAppLocked(app, false, null /* ABI override */);
11147                    }
11148                }
11149            } catch (RemoteException ex) {
11150            }
11151        }
11152    }
11153
11154    /**
11155     * When a user is unlocked, we need to install encryption-unaware providers
11156     * belonging to any running apps.
11157     */
11158    private void installEncryptionUnawareProviders(int userId) {
11159        // We're only interested in providers that are encryption unaware, and
11160        // we don't care about uninstalled apps, since there's no way they're
11161        // running at this point.
11162        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11163
11164        synchronized (this) {
11165            final int NP = mProcessNames.getMap().size();
11166            for (int ip = 0; ip < NP; ip++) {
11167                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11168                final int NA = apps.size();
11169                for (int ia = 0; ia < NA; ia++) {
11170                    final ProcessRecord app = apps.valueAt(ia);
11171                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11172
11173                    final int NG = app.pkgList.size();
11174                    for (int ig = 0; ig < NG; ig++) {
11175                        try {
11176                            final String pkgName = app.pkgList.keyAt(ig);
11177                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11178                                    .getPackageInfo(pkgName, matchFlags, userId);
11179                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11180                                for (ProviderInfo pi : pkgInfo.providers) {
11181                                    // TODO: keep in sync with generateApplicationProvidersLocked
11182                                    final boolean processMatch = Objects.equals(pi.processName,
11183                                            app.processName) || pi.multiprocess;
11184                                    final boolean userMatch = isSingleton(pi.processName,
11185                                            pi.applicationInfo, pi.name, pi.flags)
11186                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
11187                                    if (processMatch && userMatch) {
11188                                        Log.v(TAG, "Installing " + pi);
11189                                        app.thread.scheduleInstallProvider(pi);
11190                                    } else {
11191                                        Log.v(TAG, "Skipping " + pi);
11192                                    }
11193                                }
11194                            }
11195                        } catch (RemoteException ignored) {
11196                        }
11197                    }
11198                }
11199            }
11200        }
11201    }
11202
11203    /**
11204     * Allows apps to retrieve the MIME type of a URI.
11205     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11206     * users, then it does not need permission to access the ContentProvider.
11207     * Either, it needs cross-user uri grants.
11208     *
11209     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11210     *
11211     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11212     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11213     */
11214    public String getProviderMimeType(Uri uri, int userId) {
11215        enforceNotIsolatedCaller("getProviderMimeType");
11216        final String name = uri.getAuthority();
11217        int callingUid = Binder.getCallingUid();
11218        int callingPid = Binder.getCallingPid();
11219        long ident = 0;
11220        boolean clearedIdentity = false;
11221        synchronized (this) {
11222            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11223        }
11224        if (canClearIdentity(callingPid, callingUid, userId)) {
11225            clearedIdentity = true;
11226            ident = Binder.clearCallingIdentity();
11227        }
11228        ContentProviderHolder holder = null;
11229        try {
11230            holder = getContentProviderExternalUnchecked(name, null, userId);
11231            if (holder != null) {
11232                return holder.provider.getType(uri);
11233            }
11234        } catch (RemoteException e) {
11235            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11236            return null;
11237        } finally {
11238            // We need to clear the identity to call removeContentProviderExternalUnchecked
11239            if (!clearedIdentity) {
11240                ident = Binder.clearCallingIdentity();
11241            }
11242            try {
11243                if (holder != null) {
11244                    removeContentProviderExternalUnchecked(name, null, userId);
11245                }
11246            } finally {
11247                Binder.restoreCallingIdentity(ident);
11248            }
11249        }
11250
11251        return null;
11252    }
11253
11254    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11255        if (UserHandle.getUserId(callingUid) == userId) {
11256            return true;
11257        }
11258        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11259                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11260                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11261                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11262                return true;
11263        }
11264        return false;
11265    }
11266
11267    // =========================================================
11268    // GLOBAL MANAGEMENT
11269    // =========================================================
11270
11271    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11272            boolean isolated, int isolatedUid) {
11273        String proc = customProcess != null ? customProcess : info.processName;
11274        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11275        final int userId = UserHandle.getUserId(info.uid);
11276        int uid = info.uid;
11277        if (isolated) {
11278            if (isolatedUid == 0) {
11279                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11280                while (true) {
11281                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11282                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11283                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11284                    }
11285                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11286                    mNextIsolatedProcessUid++;
11287                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11288                        // No process for this uid, use it.
11289                        break;
11290                    }
11291                    stepsLeft--;
11292                    if (stepsLeft <= 0) {
11293                        return null;
11294                    }
11295                }
11296            } else {
11297                // Special case for startIsolatedProcess (internal only), where
11298                // the uid of the isolated process is specified by the caller.
11299                uid = isolatedUid;
11300            }
11301        }
11302        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11303        if (!mBooted && !mBooting
11304                && userId == UserHandle.USER_SYSTEM
11305                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11306            r.persistent = true;
11307        }
11308        addProcessNameLocked(r);
11309        return r;
11310    }
11311
11312    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11313            String abiOverride) {
11314        ProcessRecord app;
11315        if (!isolated) {
11316            app = getProcessRecordLocked(info.processName, info.uid, true);
11317        } else {
11318            app = null;
11319        }
11320
11321        if (app == null) {
11322            app = newProcessRecordLocked(info, null, isolated, 0);
11323            updateLruProcessLocked(app, false, null);
11324            updateOomAdjLocked();
11325        }
11326
11327        // This package really, really can not be stopped.
11328        try {
11329            AppGlobals.getPackageManager().setPackageStoppedState(
11330                    info.packageName, false, UserHandle.getUserId(app.uid));
11331        } catch (RemoteException e) {
11332        } catch (IllegalArgumentException e) {
11333            Slog.w(TAG, "Failed trying to unstop package "
11334                    + info.packageName + ": " + e);
11335        }
11336
11337        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11338            app.persistent = true;
11339            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11340        }
11341        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11342            mPersistentStartingProcesses.add(app);
11343            startProcessLocked(app, "added application", app.processName, abiOverride,
11344                    null /* entryPoint */, null /* entryPointArgs */);
11345        }
11346
11347        return app;
11348    }
11349
11350    public void unhandledBack() {
11351        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11352                "unhandledBack()");
11353
11354        synchronized(this) {
11355            final long origId = Binder.clearCallingIdentity();
11356            try {
11357                getFocusedStack().unhandledBackLocked();
11358            } finally {
11359                Binder.restoreCallingIdentity(origId);
11360            }
11361        }
11362    }
11363
11364    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11365        enforceNotIsolatedCaller("openContentUri");
11366        final int userId = UserHandle.getCallingUserId();
11367        String name = uri.getAuthority();
11368        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11369        ParcelFileDescriptor pfd = null;
11370        if (cph != null) {
11371            // We record the binder invoker's uid in thread-local storage before
11372            // going to the content provider to open the file.  Later, in the code
11373            // that handles all permissions checks, we look for this uid and use
11374            // that rather than the Activity Manager's own uid.  The effect is that
11375            // we do the check against the caller's permissions even though it looks
11376            // to the content provider like the Activity Manager itself is making
11377            // the request.
11378            Binder token = new Binder();
11379            sCallerIdentity.set(new Identity(
11380                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11381            try {
11382                pfd = cph.provider.openFile(null, uri, "r", null, token);
11383            } catch (FileNotFoundException e) {
11384                // do nothing; pfd will be returned null
11385            } finally {
11386                // Ensure that whatever happens, we clean up the identity state
11387                sCallerIdentity.remove();
11388                // Ensure we're done with the provider.
11389                removeContentProviderExternalUnchecked(name, null, userId);
11390            }
11391        } else {
11392            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11393        }
11394        return pfd;
11395    }
11396
11397    // Actually is sleeping or shutting down or whatever else in the future
11398    // is an inactive state.
11399    public boolean isSleepingOrShuttingDown() {
11400        return isSleeping() || mShuttingDown;
11401    }
11402
11403    public boolean isSleeping() {
11404        return mSleeping;
11405    }
11406
11407    void onWakefulnessChanged(int wakefulness) {
11408        synchronized(this) {
11409            mWakefulness = wakefulness;
11410            updateSleepIfNeededLocked();
11411        }
11412    }
11413
11414    void finishRunningVoiceLocked() {
11415        if (mRunningVoice != null) {
11416            mRunningVoice = null;
11417            mVoiceWakeLock.release();
11418            updateSleepIfNeededLocked();
11419        }
11420    }
11421
11422    void startTimeTrackingFocusedActivityLocked() {
11423        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11424            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11425        }
11426    }
11427
11428    void updateSleepIfNeededLocked() {
11429        if (mSleeping && !shouldSleepLocked()) {
11430            mSleeping = false;
11431            startTimeTrackingFocusedActivityLocked();
11432            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11433            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11434            updateOomAdjLocked();
11435        } else if (!mSleeping && shouldSleepLocked()) {
11436            mSleeping = true;
11437            if (mCurAppTimeTracker != null) {
11438                mCurAppTimeTracker.stop();
11439            }
11440            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11441            mStackSupervisor.goingToSleepLocked();
11442            updateOomAdjLocked();
11443
11444            // Initialize the wake times of all processes.
11445            checkExcessivePowerUsageLocked(false);
11446            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11447            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11448            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11449        }
11450    }
11451
11452    private boolean shouldSleepLocked() {
11453        // Resume applications while running a voice interactor.
11454        if (mRunningVoice != null) {
11455            return false;
11456        }
11457
11458        // TODO: Transform the lock screen state into a sleep token instead.
11459        switch (mWakefulness) {
11460            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11461            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11462            case PowerManagerInternal.WAKEFULNESS_DOZING:
11463                // Pause applications whenever the lock screen is shown or any sleep
11464                // tokens have been acquired.
11465                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11466            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11467            default:
11468                // If we're asleep then pause applications unconditionally.
11469                return true;
11470        }
11471    }
11472
11473    /** Pokes the task persister. */
11474    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11475        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11476    }
11477
11478    /** Notifies all listeners when the task stack has changed. */
11479    void notifyTaskStackChangedLocked() {
11480        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11481        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11482        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11483        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11484    }
11485
11486    /** Notifies all listeners when an Activity is pinned. */
11487    void notifyActivityPinnedLocked() {
11488        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11489        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11490    }
11491
11492    /**
11493     * Notifies all listeners when an attempt was made to start an an activity that is already
11494     * running in the pinned stack and the activity was not actually started, but the task is
11495     * either brought to the front or a new Intent is delivered to it.
11496     */
11497    void notifyPinnedActivityRestartAttemptLocked() {
11498        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11499        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11500    }
11501
11502    /** Notifies all listeners when the pinned stack animation ends. */
11503    @Override
11504    public void notifyPinnedStackAnimationEnded() {
11505        synchronized (this) {
11506            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11507            mHandler.obtainMessage(
11508                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11509        }
11510    }
11511
11512    @Override
11513    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11514        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11515    }
11516
11517    @Override
11518    public boolean shutdown(int timeout) {
11519        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11520                != PackageManager.PERMISSION_GRANTED) {
11521            throw new SecurityException("Requires permission "
11522                    + android.Manifest.permission.SHUTDOWN);
11523        }
11524
11525        boolean timedout = false;
11526
11527        synchronized(this) {
11528            mShuttingDown = true;
11529            updateEventDispatchingLocked();
11530            timedout = mStackSupervisor.shutdownLocked(timeout);
11531        }
11532
11533        mAppOpsService.shutdown();
11534        if (mUsageStatsService != null) {
11535            mUsageStatsService.prepareShutdown();
11536        }
11537        mBatteryStatsService.shutdown();
11538        synchronized (this) {
11539            mProcessStats.shutdownLocked();
11540            notifyTaskPersisterLocked(null, true);
11541        }
11542
11543        return timedout;
11544    }
11545
11546    public final void activitySlept(IBinder token) {
11547        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11548
11549        final long origId = Binder.clearCallingIdentity();
11550
11551        synchronized (this) {
11552            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11553            if (r != null) {
11554                mStackSupervisor.activitySleptLocked(r);
11555            }
11556        }
11557
11558        Binder.restoreCallingIdentity(origId);
11559    }
11560
11561    private String lockScreenShownToString() {
11562        switch (mLockScreenShown) {
11563            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11564            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11565            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11566            default: return "Unknown=" + mLockScreenShown;
11567        }
11568    }
11569
11570    void logLockScreen(String msg) {
11571        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11572                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11573                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11574                + " mSleeping=" + mSleeping);
11575    }
11576
11577    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11578        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11579        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11580        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11581            boolean wasRunningVoice = mRunningVoice != null;
11582            mRunningVoice = session;
11583            if (!wasRunningVoice) {
11584                mVoiceWakeLock.acquire();
11585                updateSleepIfNeededLocked();
11586            }
11587        }
11588    }
11589
11590    private void updateEventDispatchingLocked() {
11591        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11592    }
11593
11594    public void setLockScreenShown(boolean showing, boolean occluded) {
11595        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11596                != PackageManager.PERMISSION_GRANTED) {
11597            throw new SecurityException("Requires permission "
11598                    + android.Manifest.permission.DEVICE_POWER);
11599        }
11600
11601        synchronized(this) {
11602            long ident = Binder.clearCallingIdentity();
11603            try {
11604                if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11605                mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11606                if (showing && occluded) {
11607                    // The lock screen is currently showing, but is occluded by a window that can
11608                    // show on top of the lock screen. In this can we want to dismiss the docked
11609                    // stack since it will be complicated/risky to try to put the activity on top
11610                    // of the lock screen in the right fullscreen configuration.
11611                    mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11612                            mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11613                }
11614
11615                updateSleepIfNeededLocked();
11616            } finally {
11617                Binder.restoreCallingIdentity(ident);
11618            }
11619        }
11620    }
11621
11622    @Override
11623    public void notifyLockedProfile(@UserIdInt int userId) {
11624        try {
11625            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11626                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11627            }
11628        } catch (RemoteException ex) {
11629            throw new SecurityException("Fail to check is caller a privileged app", ex);
11630        }
11631
11632        synchronized (this) {
11633            if (mStackSupervisor.isUserLockedProfile(userId)) {
11634                final long ident = Binder.clearCallingIdentity();
11635                try {
11636                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11637                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11638                        // If there is no device lock, we will show the profile's credential page.
11639                        mActivityStarter.showConfirmDeviceCredential(userId);
11640                    } else {
11641                        // Showing launcher to avoid user entering credential twice.
11642                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11643                    }
11644                } finally {
11645                    Binder.restoreCallingIdentity(ident);
11646                }
11647            }
11648        }
11649    }
11650
11651    @Override
11652    public void startConfirmDeviceCredentialIntent(Intent intent) {
11653        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11654        synchronized (this) {
11655            final long ident = Binder.clearCallingIdentity();
11656            try {
11657                mActivityStarter.startConfirmCredentialIntent(intent);
11658            } finally {
11659                Binder.restoreCallingIdentity(ident);
11660            }
11661        }
11662    }
11663
11664    @Override
11665    public void stopAppSwitches() {
11666        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11667                != PackageManager.PERMISSION_GRANTED) {
11668            throw new SecurityException("viewquires permission "
11669                    + android.Manifest.permission.STOP_APP_SWITCHES);
11670        }
11671
11672        synchronized(this) {
11673            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11674                    + APP_SWITCH_DELAY_TIME;
11675            mDidAppSwitch = false;
11676            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11677            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11678            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11679        }
11680    }
11681
11682    public void resumeAppSwitches() {
11683        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11684                != PackageManager.PERMISSION_GRANTED) {
11685            throw new SecurityException("Requires permission "
11686                    + android.Manifest.permission.STOP_APP_SWITCHES);
11687        }
11688
11689        synchronized(this) {
11690            // Note that we don't execute any pending app switches... we will
11691            // let those wait until either the timeout, or the next start
11692            // activity request.
11693            mAppSwitchesAllowedTime = 0;
11694        }
11695    }
11696
11697    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11698            int callingPid, int callingUid, String name) {
11699        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11700            return true;
11701        }
11702
11703        int perm = checkComponentPermission(
11704                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11705                sourceUid, -1, true);
11706        if (perm == PackageManager.PERMISSION_GRANTED) {
11707            return true;
11708        }
11709
11710        // If the actual IPC caller is different from the logical source, then
11711        // also see if they are allowed to control app switches.
11712        if (callingUid != -1 && callingUid != sourceUid) {
11713            perm = checkComponentPermission(
11714                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11715                    callingUid, -1, true);
11716            if (perm == PackageManager.PERMISSION_GRANTED) {
11717                return true;
11718            }
11719        }
11720
11721        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11722        return false;
11723    }
11724
11725    public void setDebugApp(String packageName, boolean waitForDebugger,
11726            boolean persistent) {
11727        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11728                "setDebugApp()");
11729
11730        long ident = Binder.clearCallingIdentity();
11731        try {
11732            // Note that this is not really thread safe if there are multiple
11733            // callers into it at the same time, but that's not a situation we
11734            // care about.
11735            if (persistent) {
11736                final ContentResolver resolver = mContext.getContentResolver();
11737                Settings.Global.putString(
11738                    resolver, Settings.Global.DEBUG_APP,
11739                    packageName);
11740                Settings.Global.putInt(
11741                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11742                    waitForDebugger ? 1 : 0);
11743            }
11744
11745            synchronized (this) {
11746                if (!persistent) {
11747                    mOrigDebugApp = mDebugApp;
11748                    mOrigWaitForDebugger = mWaitForDebugger;
11749                }
11750                mDebugApp = packageName;
11751                mWaitForDebugger = waitForDebugger;
11752                mDebugTransient = !persistent;
11753                if (packageName != null) {
11754                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11755                            false, UserHandle.USER_ALL, "set debug app");
11756                }
11757            }
11758        } finally {
11759            Binder.restoreCallingIdentity(ident);
11760        }
11761    }
11762
11763    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11764        synchronized (this) {
11765            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11766            if (!isDebuggable) {
11767                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11768                    throw new SecurityException("Process not debuggable: " + app.packageName);
11769                }
11770            }
11771
11772            mTrackAllocationApp = processName;
11773        }
11774    }
11775
11776    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11777        synchronized (this) {
11778            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11779            if (!isDebuggable) {
11780                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11781                    throw new SecurityException("Process not debuggable: " + app.packageName);
11782                }
11783            }
11784            mProfileApp = processName;
11785            mProfileFile = profilerInfo.profileFile;
11786            if (mProfileFd != null) {
11787                try {
11788                    mProfileFd.close();
11789                } catch (IOException e) {
11790                }
11791                mProfileFd = null;
11792            }
11793            mProfileFd = profilerInfo.profileFd;
11794            mSamplingInterval = profilerInfo.samplingInterval;
11795            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11796            mProfileType = 0;
11797        }
11798    }
11799
11800    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11801        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11802        if (!isDebuggable) {
11803            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11804                throw new SecurityException("Process not debuggable: " + app.packageName);
11805            }
11806        }
11807        mNativeDebuggingApp = processName;
11808    }
11809
11810    @Override
11811    public void setAlwaysFinish(boolean enabled) {
11812        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11813                "setAlwaysFinish()");
11814
11815        long ident = Binder.clearCallingIdentity();
11816        try {
11817            Settings.Global.putInt(
11818                    mContext.getContentResolver(),
11819                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11820
11821            synchronized (this) {
11822                mAlwaysFinishActivities = enabled;
11823            }
11824        } finally {
11825            Binder.restoreCallingIdentity(ident);
11826        }
11827    }
11828
11829    @Override
11830    public void setLenientBackgroundCheck(boolean enabled) {
11831        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11832                "setLenientBackgroundCheck()");
11833
11834        long ident = Binder.clearCallingIdentity();
11835        try {
11836            Settings.Global.putInt(
11837                    mContext.getContentResolver(),
11838                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11839
11840            synchronized (this) {
11841                mLenientBackgroundCheck = enabled;
11842            }
11843        } finally {
11844            Binder.restoreCallingIdentity(ident);
11845        }
11846    }
11847
11848    @Override
11849    public void setActivityController(IActivityController controller, boolean imAMonkey) {
11850        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11851                "setActivityController()");
11852        synchronized (this) {
11853            mController = controller;
11854            mControllerIsAMonkey = imAMonkey;
11855            Watchdog.getInstance().setActivityController(controller);
11856        }
11857    }
11858
11859    @Override
11860    public void setUserIsMonkey(boolean userIsMonkey) {
11861        synchronized (this) {
11862            synchronized (mPidsSelfLocked) {
11863                final int callingPid = Binder.getCallingPid();
11864                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11865                if (precessRecord == null) {
11866                    throw new SecurityException("Unknown process: " + callingPid);
11867                }
11868                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11869                    throw new SecurityException("Only an instrumentation process "
11870                            + "with a UiAutomation can call setUserIsMonkey");
11871                }
11872            }
11873            mUserIsMonkey = userIsMonkey;
11874        }
11875    }
11876
11877    @Override
11878    public boolean isUserAMonkey() {
11879        synchronized (this) {
11880            // If there is a controller also implies the user is a monkey.
11881            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
11882        }
11883    }
11884
11885    public void requestBugReport(int bugreportType) {
11886        String service = null;
11887        switch (bugreportType) {
11888            case ActivityManager.BUGREPORT_OPTION_FULL:
11889                service = "bugreport";
11890                break;
11891            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
11892                service = "bugreportplus";
11893                break;
11894            case ActivityManager.BUGREPORT_OPTION_REMOTE:
11895                service = "bugreportremote";
11896                break;
11897        }
11898        if (service == null) {
11899            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
11900                    + bugreportType);
11901        }
11902        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11903        SystemProperties.set("ctl.start", service);
11904    }
11905
11906    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11907        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11908    }
11909
11910    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11911        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11912            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11913        }
11914        return KEY_DISPATCHING_TIMEOUT;
11915    }
11916
11917    @Override
11918    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11919        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11920                != PackageManager.PERMISSION_GRANTED) {
11921            throw new SecurityException("Requires permission "
11922                    + android.Manifest.permission.FILTER_EVENTS);
11923        }
11924        ProcessRecord proc;
11925        long timeout;
11926        synchronized (this) {
11927            synchronized (mPidsSelfLocked) {
11928                proc = mPidsSelfLocked.get(pid);
11929            }
11930            timeout = getInputDispatchingTimeoutLocked(proc);
11931        }
11932
11933        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
11934            return -1;
11935        }
11936
11937        return timeout;
11938    }
11939
11940    /**
11941     * Handle input dispatching timeouts.
11942     * Returns whether input dispatching should be aborted or not.
11943     */
11944    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
11945            final ActivityRecord activity, final ActivityRecord parent,
11946            final boolean aboveSystem, String reason) {
11947        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11948                != PackageManager.PERMISSION_GRANTED) {
11949            throw new SecurityException("Requires permission "
11950                    + android.Manifest.permission.FILTER_EVENTS);
11951        }
11952
11953        final String annotation;
11954        if (reason == null) {
11955            annotation = "Input dispatching timed out";
11956        } else {
11957            annotation = "Input dispatching timed out (" + reason + ")";
11958        }
11959
11960        if (proc != null) {
11961            synchronized (this) {
11962                if (proc.debugging) {
11963                    return false;
11964                }
11965
11966                if (mDidDexOpt) {
11967                    // Give more time since we were dexopting.
11968                    mDidDexOpt = false;
11969                    return false;
11970                }
11971
11972                if (proc.instrumentationClass != null) {
11973                    Bundle info = new Bundle();
11974                    info.putString("shortMsg", "keyDispatchingTimedOut");
11975                    info.putString("longMsg", annotation);
11976                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
11977                    return true;
11978                }
11979            }
11980            mHandler.post(new Runnable() {
11981                @Override
11982                public void run() {
11983                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
11984                }
11985            });
11986        }
11987
11988        return true;
11989    }
11990
11991    @Override
11992    public Bundle getAssistContextExtras(int requestType) {
11993        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
11994                null, null, true /* focused */, true /* newSessionId */,
11995                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
11996        if (pae == null) {
11997            return null;
11998        }
11999        synchronized (pae) {
12000            while (!pae.haveResult) {
12001                try {
12002                    pae.wait();
12003                } catch (InterruptedException e) {
12004                }
12005            }
12006        }
12007        synchronized (this) {
12008            buildAssistBundleLocked(pae, pae.result);
12009            mPendingAssistExtras.remove(pae);
12010            mUiHandler.removeCallbacks(pae);
12011        }
12012        return pae.extras;
12013    }
12014
12015    @Override
12016    public boolean isAssistDataAllowedOnCurrentActivity() {
12017        int userId;
12018        synchronized (this) {
12019            userId = mUserController.getCurrentUserIdLocked();
12020            ActivityRecord activity = getFocusedStack().topActivity();
12021            if (activity == null) {
12022                return false;
12023            }
12024            userId = activity.userId;
12025        }
12026        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12027                Context.DEVICE_POLICY_SERVICE);
12028        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12029    }
12030
12031    @Override
12032    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12033        long ident = Binder.clearCallingIdentity();
12034        try {
12035            synchronized (this) {
12036                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12037                ActivityRecord top = getFocusedStack().topActivity();
12038                if (top != caller) {
12039                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12040                            + " is not current top " + top);
12041                    return false;
12042                }
12043                if (!top.nowVisible) {
12044                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12045                            + " is not visible");
12046                    return false;
12047                }
12048            }
12049            AssistUtils utils = new AssistUtils(mContext);
12050            return utils.showSessionForActiveService(args,
12051                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12052        } finally {
12053            Binder.restoreCallingIdentity(ident);
12054        }
12055    }
12056
12057    @Override
12058    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12059            Bundle receiverExtras,
12060            IBinder activityToken, boolean focused, boolean newSessionId) {
12061        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12062                activityToken, focused, newSessionId,
12063                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12064                != null;
12065    }
12066
12067    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12068            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12069            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12070        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12071                "enqueueAssistContext()");
12072        synchronized (this) {
12073            ActivityRecord activity = getFocusedStack().topActivity();
12074            if (activity == null) {
12075                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12076                return null;
12077            }
12078            if (activity.app == null || activity.app.thread == null) {
12079                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12080                return null;
12081            }
12082            if (focused) {
12083                if (activityToken != null) {
12084                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12085                    if (activity != caller) {
12086                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12087                                + " is not current top " + activity);
12088                        return null;
12089                    }
12090                }
12091            } else {
12092                activity = ActivityRecord.forTokenLocked(activityToken);
12093                if (activity == null) {
12094                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12095                            + " couldn't be found");
12096                    return null;
12097                }
12098            }
12099
12100            PendingAssistExtras pae;
12101            Bundle extras = new Bundle();
12102            if (args != null) {
12103                extras.putAll(args);
12104            }
12105            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12106            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12107            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12108                    userHandle);
12109            // Increment the sessionId if necessary
12110            if (newSessionId) {
12111                mViSessionId++;
12112            }
12113            try {
12114                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12115                        requestType, mViSessionId);
12116                mPendingAssistExtras.add(pae);
12117                mUiHandler.postDelayed(pae, timeout);
12118            } catch (RemoteException e) {
12119                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12120                return null;
12121            }
12122            return pae;
12123        }
12124    }
12125
12126    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12127        IResultReceiver receiver;
12128        synchronized (this) {
12129            mPendingAssistExtras.remove(pae);
12130            receiver = pae.receiver;
12131        }
12132        if (receiver != null) {
12133            // Caller wants result sent back to them.
12134            Bundle sendBundle = new Bundle();
12135            // At least return the receiver extras
12136            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12137                    pae.receiverExtras);
12138            try {
12139                pae.receiver.send(0, sendBundle);
12140            } catch (RemoteException e) {
12141            }
12142        }
12143    }
12144
12145    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12146        if (result != null) {
12147            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12148        }
12149        if (pae.hint != null) {
12150            pae.extras.putBoolean(pae.hint, true);
12151        }
12152    }
12153
12154    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12155            AssistContent content, Uri referrer) {
12156        PendingAssistExtras pae = (PendingAssistExtras)token;
12157        synchronized (pae) {
12158            pae.result = extras;
12159            pae.structure = structure;
12160            pae.content = content;
12161            if (referrer != null) {
12162                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12163            }
12164            pae.haveResult = true;
12165            pae.notifyAll();
12166            if (pae.intent == null && pae.receiver == null) {
12167                // Caller is just waiting for the result.
12168                return;
12169            }
12170        }
12171
12172        // We are now ready to launch the assist activity.
12173        IResultReceiver sendReceiver = null;
12174        Bundle sendBundle = null;
12175        synchronized (this) {
12176            buildAssistBundleLocked(pae, extras);
12177            boolean exists = mPendingAssistExtras.remove(pae);
12178            mUiHandler.removeCallbacks(pae);
12179            if (!exists) {
12180                // Timed out.
12181                return;
12182            }
12183            if ((sendReceiver=pae.receiver) != null) {
12184                // Caller wants result sent back to them.
12185                sendBundle = new Bundle();
12186                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12187                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12188                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12189                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12190                        pae.receiverExtras);
12191            }
12192        }
12193        if (sendReceiver != null) {
12194            try {
12195                sendReceiver.send(0, sendBundle);
12196            } catch (RemoteException e) {
12197            }
12198            return;
12199        }
12200
12201        long ident = Binder.clearCallingIdentity();
12202        try {
12203            pae.intent.replaceExtras(pae.extras);
12204            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12205                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12206                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12207            closeSystemDialogs("assist");
12208            try {
12209                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12210            } catch (ActivityNotFoundException e) {
12211                Slog.w(TAG, "No activity to handle assist action.", e);
12212            }
12213        } finally {
12214            Binder.restoreCallingIdentity(ident);
12215        }
12216    }
12217
12218    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12219            Bundle args) {
12220        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12221                true /* focused */, true /* newSessionId */,
12222                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12223    }
12224
12225    public void registerProcessObserver(IProcessObserver observer) {
12226        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12227                "registerProcessObserver()");
12228        synchronized (this) {
12229            mProcessObservers.register(observer);
12230        }
12231    }
12232
12233    @Override
12234    public void unregisterProcessObserver(IProcessObserver observer) {
12235        synchronized (this) {
12236            mProcessObservers.unregister(observer);
12237        }
12238    }
12239
12240    @Override
12241    public void registerUidObserver(IUidObserver observer, int which) {
12242        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12243                "registerUidObserver()");
12244        synchronized (this) {
12245            mUidObservers.register(observer, which);
12246        }
12247    }
12248
12249    @Override
12250    public void unregisterUidObserver(IUidObserver observer) {
12251        synchronized (this) {
12252            mUidObservers.unregister(observer);
12253        }
12254    }
12255
12256    @Override
12257    public boolean convertFromTranslucent(IBinder token) {
12258        final long origId = Binder.clearCallingIdentity();
12259        try {
12260            synchronized (this) {
12261                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12262                if (r == null) {
12263                    return false;
12264                }
12265                final boolean translucentChanged = r.changeWindowTranslucency(true);
12266                if (translucentChanged) {
12267                    r.task.stack.releaseBackgroundResources(r);
12268                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12269                }
12270                mWindowManager.setAppFullscreen(token, true);
12271                return translucentChanged;
12272            }
12273        } finally {
12274            Binder.restoreCallingIdentity(origId);
12275        }
12276    }
12277
12278    @Override
12279    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12280        final long origId = Binder.clearCallingIdentity();
12281        try {
12282            synchronized (this) {
12283                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12284                if (r == null) {
12285                    return false;
12286                }
12287                int index = r.task.mActivities.lastIndexOf(r);
12288                if (index > 0) {
12289                    ActivityRecord under = r.task.mActivities.get(index - 1);
12290                    under.returningOptions = options;
12291                }
12292                final boolean translucentChanged = r.changeWindowTranslucency(false);
12293                if (translucentChanged) {
12294                    r.task.stack.convertActivityToTranslucent(r);
12295                }
12296                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12297                mWindowManager.setAppFullscreen(token, false);
12298                return translucentChanged;
12299            }
12300        } finally {
12301            Binder.restoreCallingIdentity(origId);
12302        }
12303    }
12304
12305    @Override
12306    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12307        final long origId = Binder.clearCallingIdentity();
12308        try {
12309            synchronized (this) {
12310                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12311                if (r != null) {
12312                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12313                }
12314            }
12315            return false;
12316        } finally {
12317            Binder.restoreCallingIdentity(origId);
12318        }
12319    }
12320
12321    @Override
12322    public boolean isBackgroundVisibleBehind(IBinder token) {
12323        final long origId = Binder.clearCallingIdentity();
12324        try {
12325            synchronized (this) {
12326                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12327                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12328                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12329                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12330                return visible;
12331            }
12332        } finally {
12333            Binder.restoreCallingIdentity(origId);
12334        }
12335    }
12336
12337    @Override
12338    public ActivityOptions getActivityOptions(IBinder token) {
12339        final long origId = Binder.clearCallingIdentity();
12340        try {
12341            synchronized (this) {
12342                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12343                if (r != null) {
12344                    final ActivityOptions activityOptions = r.pendingOptions;
12345                    r.pendingOptions = null;
12346                    return activityOptions;
12347                }
12348                return null;
12349            }
12350        } finally {
12351            Binder.restoreCallingIdentity(origId);
12352        }
12353    }
12354
12355    @Override
12356    public void setImmersive(IBinder token, boolean immersive) {
12357        synchronized(this) {
12358            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12359            if (r == null) {
12360                throw new IllegalArgumentException();
12361            }
12362            r.immersive = immersive;
12363
12364            // update associated state if we're frontmost
12365            if (r == mFocusedActivity) {
12366                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12367                applyUpdateLockStateLocked(r);
12368            }
12369        }
12370    }
12371
12372    @Override
12373    public boolean isImmersive(IBinder token) {
12374        synchronized (this) {
12375            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12376            if (r == null) {
12377                throw new IllegalArgumentException();
12378            }
12379            return r.immersive;
12380        }
12381    }
12382
12383    @Override
12384    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12385        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12386            throw new UnsupportedOperationException("VR mode not supported on this device!");
12387        }
12388
12389        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12390
12391        ActivityRecord r;
12392        synchronized (this) {
12393            r = ActivityRecord.isInStackLocked(token);
12394        }
12395
12396        if (r == null) {
12397            throw new IllegalArgumentException();
12398        }
12399
12400        int err;
12401        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12402                VrManagerInternal.NO_ERROR) {
12403            return err;
12404        }
12405
12406        synchronized(this) {
12407            r.requestedVrComponent = (enabled) ? packageName : null;
12408
12409            // Update associated state if this activity is currently focused
12410            if (r == mFocusedActivity) {
12411                applyUpdateVrModeLocked(r);
12412            }
12413            return 0;
12414        }
12415    }
12416
12417    @Override
12418    public boolean isVrModePackageEnabled(ComponentName packageName) {
12419        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12420            throw new UnsupportedOperationException("VR mode not supported on this device!");
12421        }
12422
12423        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12424
12425        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12426                VrManagerInternal.NO_ERROR;
12427    }
12428
12429    public boolean isTopActivityImmersive() {
12430        enforceNotIsolatedCaller("startActivity");
12431        synchronized (this) {
12432            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12433            return (r != null) ? r.immersive : false;
12434        }
12435    }
12436
12437    @Override
12438    public boolean isTopOfTask(IBinder token) {
12439        synchronized (this) {
12440            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12441            if (r == null) {
12442                throw new IllegalArgumentException();
12443            }
12444            return r.task.getTopActivity() == r;
12445        }
12446    }
12447
12448    public final void enterSafeMode() {
12449        synchronized(this) {
12450            // It only makes sense to do this before the system is ready
12451            // and started launching other packages.
12452            if (!mSystemReady) {
12453                try {
12454                    AppGlobals.getPackageManager().enterSafeMode();
12455                } catch (RemoteException e) {
12456                }
12457            }
12458
12459            mSafeMode = true;
12460        }
12461    }
12462
12463    public final void showSafeModeOverlay() {
12464        View v = LayoutInflater.from(mContext).inflate(
12465                com.android.internal.R.layout.safe_mode, null);
12466        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12467        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12468        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12469        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12470        lp.gravity = Gravity.BOTTOM | Gravity.START;
12471        lp.format = v.getBackground().getOpacity();
12472        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12473                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12474        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12475        ((WindowManager)mContext.getSystemService(
12476                Context.WINDOW_SERVICE)).addView(v, lp);
12477    }
12478
12479    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12480        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12481            return;
12482        }
12483        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12484        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12485        synchronized (stats) {
12486            if (mBatteryStatsService.isOnBattery()) {
12487                mBatteryStatsService.enforceCallingPermission();
12488                int MY_UID = Binder.getCallingUid();
12489                final int uid;
12490                if (sender == null) {
12491                    uid = sourceUid;
12492                } else {
12493                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12494                }
12495                BatteryStatsImpl.Uid.Pkg pkg =
12496                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12497                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12498                pkg.noteWakeupAlarmLocked(tag);
12499            }
12500        }
12501    }
12502
12503    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12504        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12505            return;
12506        }
12507        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12508        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12509        synchronized (stats) {
12510            mBatteryStatsService.enforceCallingPermission();
12511            int MY_UID = Binder.getCallingUid();
12512            final int uid;
12513            if (sender == null) {
12514                uid = sourceUid;
12515            } else {
12516                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12517            }
12518            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12519        }
12520    }
12521
12522    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12523        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12524            return;
12525        }
12526        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12527        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12528        synchronized (stats) {
12529            mBatteryStatsService.enforceCallingPermission();
12530            int MY_UID = Binder.getCallingUid();
12531            final int uid;
12532            if (sender == null) {
12533                uid = sourceUid;
12534            } else {
12535                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12536            }
12537            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12538        }
12539    }
12540
12541    public boolean killPids(int[] pids, String pReason, boolean secure) {
12542        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12543            throw new SecurityException("killPids only available to the system");
12544        }
12545        String reason = (pReason == null) ? "Unknown" : pReason;
12546        // XXX Note: don't acquire main activity lock here, because the window
12547        // manager calls in with its locks held.
12548
12549        boolean killed = false;
12550        synchronized (mPidsSelfLocked) {
12551            int worstType = 0;
12552            for (int i=0; i<pids.length; i++) {
12553                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12554                if (proc != null) {
12555                    int type = proc.setAdj;
12556                    if (type > worstType) {
12557                        worstType = type;
12558                    }
12559                }
12560            }
12561
12562            // If the worst oom_adj is somewhere in the cached proc LRU range,
12563            // then constrain it so we will kill all cached procs.
12564            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12565                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12566                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12567            }
12568
12569            // If this is not a secure call, don't let it kill processes that
12570            // are important.
12571            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12572                worstType = ProcessList.SERVICE_ADJ;
12573            }
12574
12575            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12576            for (int i=0; i<pids.length; i++) {
12577                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12578                if (proc == null) {
12579                    continue;
12580                }
12581                int adj = proc.setAdj;
12582                if (adj >= worstType && !proc.killedByAm) {
12583                    proc.kill(reason, true);
12584                    killed = true;
12585                }
12586            }
12587        }
12588        return killed;
12589    }
12590
12591    @Override
12592    public void killUid(int appId, int userId, String reason) {
12593        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12594        synchronized (this) {
12595            final long identity = Binder.clearCallingIdentity();
12596            try {
12597                killPackageProcessesLocked(null, appId, userId,
12598                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12599                        reason != null ? reason : "kill uid");
12600            } finally {
12601                Binder.restoreCallingIdentity(identity);
12602            }
12603        }
12604    }
12605
12606    @Override
12607    public boolean killProcessesBelowForeground(String reason) {
12608        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12609            throw new SecurityException("killProcessesBelowForeground() only available to system");
12610        }
12611
12612        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12613    }
12614
12615    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12616        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12617            throw new SecurityException("killProcessesBelowAdj() only available to system");
12618        }
12619
12620        boolean killed = false;
12621        synchronized (mPidsSelfLocked) {
12622            final int size = mPidsSelfLocked.size();
12623            for (int i = 0; i < size; i++) {
12624                final int pid = mPidsSelfLocked.keyAt(i);
12625                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12626                if (proc == null) continue;
12627
12628                final int adj = proc.setAdj;
12629                if (adj > belowAdj && !proc.killedByAm) {
12630                    proc.kill(reason, true);
12631                    killed = true;
12632                }
12633            }
12634        }
12635        return killed;
12636    }
12637
12638    @Override
12639    public void hang(final IBinder who, boolean allowRestart) {
12640        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12641                != PackageManager.PERMISSION_GRANTED) {
12642            throw new SecurityException("Requires permission "
12643                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12644        }
12645
12646        final IBinder.DeathRecipient death = new DeathRecipient() {
12647            @Override
12648            public void binderDied() {
12649                synchronized (this) {
12650                    notifyAll();
12651                }
12652            }
12653        };
12654
12655        try {
12656            who.linkToDeath(death, 0);
12657        } catch (RemoteException e) {
12658            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12659            return;
12660        }
12661
12662        synchronized (this) {
12663            Watchdog.getInstance().setAllowRestart(allowRestart);
12664            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12665            synchronized (death) {
12666                while (who.isBinderAlive()) {
12667                    try {
12668                        death.wait();
12669                    } catch (InterruptedException e) {
12670                    }
12671                }
12672            }
12673            Watchdog.getInstance().setAllowRestart(true);
12674        }
12675    }
12676
12677    @Override
12678    public void restart() {
12679        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12680                != PackageManager.PERMISSION_GRANTED) {
12681            throw new SecurityException("Requires permission "
12682                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12683        }
12684
12685        Log.i(TAG, "Sending shutdown broadcast...");
12686
12687        BroadcastReceiver br = new BroadcastReceiver() {
12688            @Override public void onReceive(Context context, Intent intent) {
12689                // Now the broadcast is done, finish up the low-level shutdown.
12690                Log.i(TAG, "Shutting down activity manager...");
12691                shutdown(10000);
12692                Log.i(TAG, "Shutdown complete, restarting!");
12693                Process.killProcess(Process.myPid());
12694                System.exit(10);
12695            }
12696        };
12697
12698        // First send the high-level shut down broadcast.
12699        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12700        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12701        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12702        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12703        mContext.sendOrderedBroadcastAsUser(intent,
12704                UserHandle.ALL, null, br, mHandler, 0, null, null);
12705        */
12706        br.onReceive(mContext, intent);
12707    }
12708
12709    private long getLowRamTimeSinceIdle(long now) {
12710        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12711    }
12712
12713    @Override
12714    public void performIdleMaintenance() {
12715        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12716                != PackageManager.PERMISSION_GRANTED) {
12717            throw new SecurityException("Requires permission "
12718                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12719        }
12720
12721        synchronized (this) {
12722            final long now = SystemClock.uptimeMillis();
12723            final long timeSinceLastIdle = now - mLastIdleTime;
12724            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12725            mLastIdleTime = now;
12726            mLowRamTimeSinceLastIdle = 0;
12727            if (mLowRamStartTime != 0) {
12728                mLowRamStartTime = now;
12729            }
12730
12731            StringBuilder sb = new StringBuilder(128);
12732            sb.append("Idle maintenance over ");
12733            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12734            sb.append(" low RAM for ");
12735            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12736            Slog.i(TAG, sb.toString());
12737
12738            // If at least 1/3 of our time since the last idle period has been spent
12739            // with RAM low, then we want to kill processes.
12740            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12741
12742            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12743                ProcessRecord proc = mLruProcesses.get(i);
12744                if (proc.notCachedSinceIdle) {
12745                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12746                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12747                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12748                        if (doKilling && proc.initialIdlePss != 0
12749                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12750                            sb = new StringBuilder(128);
12751                            sb.append("Kill");
12752                            sb.append(proc.processName);
12753                            sb.append(" in idle maint: pss=");
12754                            sb.append(proc.lastPss);
12755                            sb.append(", swapPss=");
12756                            sb.append(proc.lastSwapPss);
12757                            sb.append(", initialPss=");
12758                            sb.append(proc.initialIdlePss);
12759                            sb.append(", period=");
12760                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12761                            sb.append(", lowRamPeriod=");
12762                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12763                            Slog.wtfQuiet(TAG, sb.toString());
12764                            proc.kill("idle maint (pss " + proc.lastPss
12765                                    + " from " + proc.initialIdlePss + ")", true);
12766                        }
12767                    }
12768                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12769                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12770                    proc.notCachedSinceIdle = true;
12771                    proc.initialIdlePss = 0;
12772                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12773                            mTestPssMode, isSleeping(), now);
12774                }
12775            }
12776
12777            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12778            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12779        }
12780    }
12781
12782    @Override
12783    public void sendIdleJobTrigger() {
12784        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12785                != PackageManager.PERMISSION_GRANTED) {
12786            throw new SecurityException("Requires permission "
12787                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12788        }
12789
12790        final long ident = Binder.clearCallingIdentity();
12791        try {
12792            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
12793                    .setPackage("android")
12794                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12795            broadcastIntent(null, intent, null, null, 0, null, null, null,
12796                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
12797        } finally {
12798            Binder.restoreCallingIdentity(ident);
12799        }
12800    }
12801
12802    private void retrieveSettings() {
12803        final ContentResolver resolver = mContext.getContentResolver();
12804        final boolean freeformWindowManagement =
12805                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12806                        || Settings.Global.getInt(
12807                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12808        final boolean supportsPictureInPicture =
12809                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12810
12811        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12812        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12813        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12814        final boolean alwaysFinishActivities =
12815                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12816        final boolean lenientBackgroundCheck =
12817                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12818        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12819        final boolean forceResizable = Settings.Global.getInt(
12820                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12821        // Transfer any global setting for forcing RTL layout, into a System Property
12822        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12823
12824        final Configuration configuration = new Configuration();
12825        Settings.System.getConfiguration(resolver, configuration);
12826        if (forceRtl) {
12827            // This will take care of setting the correct layout direction flags
12828            configuration.setLayoutDirection(configuration.locale);
12829        }
12830
12831        synchronized (this) {
12832            mDebugApp = mOrigDebugApp = debugApp;
12833            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12834            mAlwaysFinishActivities = alwaysFinishActivities;
12835            mLenientBackgroundCheck = lenientBackgroundCheck;
12836            mForceResizableActivities = forceResizable;
12837            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12838            if (supportsMultiWindow || forceResizable) {
12839                mSupportsMultiWindow = true;
12840                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12841                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12842            } else {
12843                mSupportsMultiWindow = false;
12844                mSupportsFreeformWindowManagement = false;
12845                mSupportsPictureInPicture = false;
12846            }
12847            // This happens before any activities are started, so we can
12848            // change mConfiguration in-place.
12849            updateConfigurationLocked(configuration, null, true);
12850            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12851                    "Initial config: " + mConfiguration);
12852
12853            // Load resources only after the current configuration has been set.
12854            final Resources res = mContext.getResources();
12855            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12856            mThumbnailWidth = res.getDimensionPixelSize(
12857                    com.android.internal.R.dimen.thumbnail_width);
12858            mThumbnailHeight = res.getDimensionPixelSize(
12859                    com.android.internal.R.dimen.thumbnail_height);
12860            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12861                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
12862            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12863                    com.android.internal.R.string.config_appsNotReportingCrashes));
12864            if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
12865                mFullscreenThumbnailScale = (float) res
12866                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
12867                    (float) mConfiguration.screenWidthDp;
12868            } else {
12869                mFullscreenThumbnailScale = res.getFraction(
12870                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
12871            }
12872        }
12873    }
12874
12875    public boolean testIsSystemReady() {
12876        // no need to synchronize(this) just to read & return the value
12877        return mSystemReady;
12878    }
12879
12880    public void systemReady(final Runnable goingCallback) {
12881        synchronized(this) {
12882            if (mSystemReady) {
12883                // If we're done calling all the receivers, run the next "boot phase" passed in
12884                // by the SystemServer
12885                if (goingCallback != null) {
12886                    goingCallback.run();
12887                }
12888                return;
12889            }
12890
12891            mLocalDeviceIdleController
12892                    = LocalServices.getService(DeviceIdleController.LocalService.class);
12893
12894            // Make sure we have the current profile info, since it is needed for security checks.
12895            mUserController.onSystemReady();
12896            mRecentTasks.onSystemReadyLocked();
12897            mAppOpsService.systemReady();
12898            mSystemReady = true;
12899        }
12900
12901        ArrayList<ProcessRecord> procsToKill = null;
12902        synchronized(mPidsSelfLocked) {
12903            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12904                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12905                if (!isAllowedWhileBooting(proc.info)){
12906                    if (procsToKill == null) {
12907                        procsToKill = new ArrayList<ProcessRecord>();
12908                    }
12909                    procsToKill.add(proc);
12910                }
12911            }
12912        }
12913
12914        synchronized(this) {
12915            if (procsToKill != null) {
12916                for (int i=procsToKill.size()-1; i>=0; i--) {
12917                    ProcessRecord proc = procsToKill.get(i);
12918                    Slog.i(TAG, "Removing system update proc: " + proc);
12919                    removeProcessLocked(proc, true, false, "system update done");
12920                }
12921            }
12922
12923            // Now that we have cleaned up any update processes, we
12924            // are ready to start launching real processes and know that
12925            // we won't trample on them any more.
12926            mProcessesReady = true;
12927        }
12928
12929        Slog.i(TAG, "System now ready");
12930        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
12931            SystemClock.uptimeMillis());
12932
12933        synchronized(this) {
12934            // Make sure we have no pre-ready processes sitting around.
12935
12936            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12937                ResolveInfo ri = mContext.getPackageManager()
12938                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
12939                                STOCK_PM_FLAGS);
12940                CharSequence errorMsg = null;
12941                if (ri != null) {
12942                    ActivityInfo ai = ri.activityInfo;
12943                    ApplicationInfo app = ai.applicationInfo;
12944                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12945                        mTopAction = Intent.ACTION_FACTORY_TEST;
12946                        mTopData = null;
12947                        mTopComponent = new ComponentName(app.packageName,
12948                                ai.name);
12949                    } else {
12950                        errorMsg = mContext.getResources().getText(
12951                                com.android.internal.R.string.factorytest_not_system);
12952                    }
12953                } else {
12954                    errorMsg = mContext.getResources().getText(
12955                            com.android.internal.R.string.factorytest_no_action);
12956                }
12957                if (errorMsg != null) {
12958                    mTopAction = null;
12959                    mTopData = null;
12960                    mTopComponent = null;
12961                    Message msg = Message.obtain();
12962                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
12963                    msg.getData().putCharSequence("msg", errorMsg);
12964                    mUiHandler.sendMessage(msg);
12965                }
12966            }
12967        }
12968
12969        retrieveSettings();
12970        final int currentUserId;
12971        synchronized (this) {
12972            currentUserId = mUserController.getCurrentUserIdLocked();
12973            readGrantedUriPermissionsLocked();
12974        }
12975
12976        if (goingCallback != null) goingCallback.run();
12977
12978        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
12979                Integer.toString(currentUserId), currentUserId);
12980        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
12981                Integer.toString(currentUserId), currentUserId);
12982        mSystemServiceManager.startUser(currentUserId);
12983
12984        synchronized (this) {
12985            // Only start up encryption-aware persistent apps; once user is
12986            // unlocked we'll come back around and start unaware apps
12987            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
12988
12989            // Start up initial activity.
12990            mBooting = true;
12991            // Enable home activity for system user, so that the system can always boot
12992            if (UserManager.isSplitSystemUser()) {
12993                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
12994                try {
12995                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
12996                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
12997                            UserHandle.USER_SYSTEM);
12998                } catch (RemoteException e) {
12999                    throw e.rethrowAsRuntimeException();
13000                }
13001            }
13002            startHomeActivityLocked(currentUserId, "systemReady");
13003
13004            try {
13005                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13006                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13007                            + " data partition or your device will be unstable.");
13008                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13009                }
13010            } catch (RemoteException e) {
13011            }
13012
13013            if (!Build.isBuildConsistent()) {
13014                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13015                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13016            }
13017
13018            long ident = Binder.clearCallingIdentity();
13019            try {
13020                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13021                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13022                        | Intent.FLAG_RECEIVER_FOREGROUND);
13023                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13024                broadcastIntentLocked(null, null, intent,
13025                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13026                        null, false, false, MY_PID, Process.SYSTEM_UID,
13027                        currentUserId);
13028                intent = new Intent(Intent.ACTION_USER_STARTING);
13029                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13030                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13031                broadcastIntentLocked(null, null, intent,
13032                        null, new IIntentReceiver.Stub() {
13033                            @Override
13034                            public void performReceive(Intent intent, int resultCode, String data,
13035                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13036                                    throws RemoteException {
13037                            }
13038                        }, 0, null, null,
13039                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13040                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13041            } catch (Throwable t) {
13042                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13043            } finally {
13044                Binder.restoreCallingIdentity(ident);
13045            }
13046            mStackSupervisor.resumeFocusedStackTopActivityLocked();
13047            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13048        }
13049    }
13050
13051    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13052        synchronized (this) {
13053            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13054        }
13055    }
13056
13057    void skipCurrentReceiverLocked(ProcessRecord app) {
13058        for (BroadcastQueue queue : mBroadcastQueues) {
13059            queue.skipCurrentReceiverLocked(app);
13060        }
13061    }
13062
13063    /**
13064     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13065     * The application process will exit immediately after this call returns.
13066     * @param app object of the crashing app, null for the system server
13067     * @param crashInfo describing the exception
13068     */
13069    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13070        ProcessRecord r = findAppProcess(app, "Crash");
13071        final String processName = app == null ? "system_server"
13072                : (r == null ? "unknown" : r.processName);
13073
13074        handleApplicationCrashInner("crash", r, processName, crashInfo);
13075    }
13076
13077    /* Native crash reporting uses this inner version because it needs to be somewhat
13078     * decoupled from the AM-managed cleanup lifecycle
13079     */
13080    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13081            ApplicationErrorReport.CrashInfo crashInfo) {
13082        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13083                UserHandle.getUserId(Binder.getCallingUid()), processName,
13084                r == null ? -1 : r.info.flags,
13085                crashInfo.exceptionClassName,
13086                crashInfo.exceptionMessage,
13087                crashInfo.throwFileName,
13088                crashInfo.throwLineNumber);
13089
13090        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13091
13092        mAppErrors.crashApplication(r, crashInfo);
13093    }
13094
13095    public void handleApplicationStrictModeViolation(
13096            IBinder app,
13097            int violationMask,
13098            StrictMode.ViolationInfo info) {
13099        ProcessRecord r = findAppProcess(app, "StrictMode");
13100        if (r == null) {
13101            return;
13102        }
13103
13104        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13105            Integer stackFingerprint = info.hashCode();
13106            boolean logIt = true;
13107            synchronized (mAlreadyLoggedViolatedStacks) {
13108                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13109                    logIt = false;
13110                    // TODO: sub-sample into EventLog for these, with
13111                    // the info.durationMillis?  Then we'd get
13112                    // the relative pain numbers, without logging all
13113                    // the stack traces repeatedly.  We'd want to do
13114                    // likewise in the client code, which also does
13115                    // dup suppression, before the Binder call.
13116                } else {
13117                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13118                        mAlreadyLoggedViolatedStacks.clear();
13119                    }
13120                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13121                }
13122            }
13123            if (logIt) {
13124                logStrictModeViolationToDropBox(r, info);
13125            }
13126        }
13127
13128        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13129            AppErrorResult result = new AppErrorResult();
13130            synchronized (this) {
13131                final long origId = Binder.clearCallingIdentity();
13132
13133                Message msg = Message.obtain();
13134                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13135                HashMap<String, Object> data = new HashMap<String, Object>();
13136                data.put("result", result);
13137                data.put("app", r);
13138                data.put("violationMask", violationMask);
13139                data.put("info", info);
13140                msg.obj = data;
13141                mUiHandler.sendMessage(msg);
13142
13143                Binder.restoreCallingIdentity(origId);
13144            }
13145            int res = result.get();
13146            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13147        }
13148    }
13149
13150    // Depending on the policy in effect, there could be a bunch of
13151    // these in quick succession so we try to batch these together to
13152    // minimize disk writes, number of dropbox entries, and maximize
13153    // compression, by having more fewer, larger records.
13154    private void logStrictModeViolationToDropBox(
13155            ProcessRecord process,
13156            StrictMode.ViolationInfo info) {
13157        if (info == null) {
13158            return;
13159        }
13160        final boolean isSystemApp = process == null ||
13161                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13162                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13163        final String processName = process == null ? "unknown" : process.processName;
13164        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13165        final DropBoxManager dbox = (DropBoxManager)
13166                mContext.getSystemService(Context.DROPBOX_SERVICE);
13167
13168        // Exit early if the dropbox isn't configured to accept this report type.
13169        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13170
13171        boolean bufferWasEmpty;
13172        boolean needsFlush;
13173        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13174        synchronized (sb) {
13175            bufferWasEmpty = sb.length() == 0;
13176            appendDropBoxProcessHeaders(process, processName, sb);
13177            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13178            sb.append("System-App: ").append(isSystemApp).append("\n");
13179            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13180            if (info.violationNumThisLoop != 0) {
13181                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13182            }
13183            if (info.numAnimationsRunning != 0) {
13184                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13185            }
13186            if (info.broadcastIntentAction != null) {
13187                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13188            }
13189            if (info.durationMillis != -1) {
13190                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13191            }
13192            if (info.numInstances != -1) {
13193                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13194            }
13195            if (info.tags != null) {
13196                for (String tag : info.tags) {
13197                    sb.append("Span-Tag: ").append(tag).append("\n");
13198                }
13199            }
13200            sb.append("\n");
13201            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13202                sb.append(info.crashInfo.stackTrace);
13203                sb.append("\n");
13204            }
13205            if (info.message != null) {
13206                sb.append(info.message);
13207                sb.append("\n");
13208            }
13209
13210            // Only buffer up to ~64k.  Various logging bits truncate
13211            // things at 128k.
13212            needsFlush = (sb.length() > 64 * 1024);
13213        }
13214
13215        // Flush immediately if the buffer's grown too large, or this
13216        // is a non-system app.  Non-system apps are isolated with a
13217        // different tag & policy and not batched.
13218        //
13219        // Batching is useful during internal testing with
13220        // StrictMode settings turned up high.  Without batching,
13221        // thousands of separate files could be created on boot.
13222        if (!isSystemApp || needsFlush) {
13223            new Thread("Error dump: " + dropboxTag) {
13224                @Override
13225                public void run() {
13226                    String report;
13227                    synchronized (sb) {
13228                        report = sb.toString();
13229                        sb.delete(0, sb.length());
13230                        sb.trimToSize();
13231                    }
13232                    if (report.length() != 0) {
13233                        dbox.addText(dropboxTag, report);
13234                    }
13235                }
13236            }.start();
13237            return;
13238        }
13239
13240        // System app batching:
13241        if (!bufferWasEmpty) {
13242            // An existing dropbox-writing thread is outstanding, so
13243            // we don't need to start it up.  The existing thread will
13244            // catch the buffer appends we just did.
13245            return;
13246        }
13247
13248        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13249        // (After this point, we shouldn't access AMS internal data structures.)
13250        new Thread("Error dump: " + dropboxTag) {
13251            @Override
13252            public void run() {
13253                // 5 second sleep to let stacks arrive and be batched together
13254                try {
13255                    Thread.sleep(5000);  // 5 seconds
13256                } catch (InterruptedException e) {}
13257
13258                String errorReport;
13259                synchronized (mStrictModeBuffer) {
13260                    errorReport = mStrictModeBuffer.toString();
13261                    if (errorReport.length() == 0) {
13262                        return;
13263                    }
13264                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13265                    mStrictModeBuffer.trimToSize();
13266                }
13267                dbox.addText(dropboxTag, errorReport);
13268            }
13269        }.start();
13270    }
13271
13272    /**
13273     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13274     * @param app object of the crashing app, null for the system server
13275     * @param tag reported by the caller
13276     * @param system whether this wtf is coming from the system
13277     * @param crashInfo describing the context of the error
13278     * @return true if the process should exit immediately (WTF is fatal)
13279     */
13280    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13281            final ApplicationErrorReport.CrashInfo crashInfo) {
13282        final int callingUid = Binder.getCallingUid();
13283        final int callingPid = Binder.getCallingPid();
13284
13285        if (system) {
13286            // If this is coming from the system, we could very well have low-level
13287            // system locks held, so we want to do this all asynchronously.  And we
13288            // never want this to become fatal, so there is that too.
13289            mHandler.post(new Runnable() {
13290                @Override public void run() {
13291                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13292                }
13293            });
13294            return false;
13295        }
13296
13297        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13298                crashInfo);
13299
13300        if (r != null && r.pid != Process.myPid() &&
13301                Settings.Global.getInt(mContext.getContentResolver(),
13302                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13303            mAppErrors.crashApplication(r, crashInfo);
13304            return true;
13305        } else {
13306            return false;
13307        }
13308    }
13309
13310    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13311            final ApplicationErrorReport.CrashInfo crashInfo) {
13312        final ProcessRecord r = findAppProcess(app, "WTF");
13313        final String processName = app == null ? "system_server"
13314                : (r == null ? "unknown" : r.processName);
13315
13316        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13317                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13318
13319        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13320
13321        return r;
13322    }
13323
13324    /**
13325     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13326     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13327     */
13328    private ProcessRecord findAppProcess(IBinder app, String reason) {
13329        if (app == null) {
13330            return null;
13331        }
13332
13333        synchronized (this) {
13334            final int NP = mProcessNames.getMap().size();
13335            for (int ip=0; ip<NP; ip++) {
13336                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13337                final int NA = apps.size();
13338                for (int ia=0; ia<NA; ia++) {
13339                    ProcessRecord p = apps.valueAt(ia);
13340                    if (p.thread != null && p.thread.asBinder() == app) {
13341                        return p;
13342                    }
13343                }
13344            }
13345
13346            Slog.w(TAG, "Can't find mystery application for " + reason
13347                    + " from pid=" + Binder.getCallingPid()
13348                    + " uid=" + Binder.getCallingUid() + ": " + app);
13349            return null;
13350        }
13351    }
13352
13353    /**
13354     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13355     * to append various headers to the dropbox log text.
13356     */
13357    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13358            StringBuilder sb) {
13359        // Watchdog thread ends up invoking this function (with
13360        // a null ProcessRecord) to add the stack file to dropbox.
13361        // Do not acquire a lock on this (am) in such cases, as it
13362        // could cause a potential deadlock, if and when watchdog
13363        // is invoked due to unavailability of lock on am and it
13364        // would prevent watchdog from killing system_server.
13365        if (process == null) {
13366            sb.append("Process: ").append(processName).append("\n");
13367            return;
13368        }
13369        // Note: ProcessRecord 'process' is guarded by the service
13370        // instance.  (notably process.pkgList, which could otherwise change
13371        // concurrently during execution of this method)
13372        synchronized (this) {
13373            sb.append("Process: ").append(processName).append("\n");
13374            int flags = process.info.flags;
13375            IPackageManager pm = AppGlobals.getPackageManager();
13376            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13377            for (int ip=0; ip<process.pkgList.size(); ip++) {
13378                String pkg = process.pkgList.keyAt(ip);
13379                sb.append("Package: ").append(pkg);
13380                try {
13381                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13382                    if (pi != null) {
13383                        sb.append(" v").append(pi.versionCode);
13384                        if (pi.versionName != null) {
13385                            sb.append(" (").append(pi.versionName).append(")");
13386                        }
13387                    }
13388                } catch (RemoteException e) {
13389                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13390                }
13391                sb.append("\n");
13392            }
13393        }
13394    }
13395
13396    private static String processClass(ProcessRecord process) {
13397        if (process == null || process.pid == MY_PID) {
13398            return "system_server";
13399        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13400            return "system_app";
13401        } else {
13402            return "data_app";
13403        }
13404    }
13405
13406    private volatile long mWtfClusterStart;
13407    private volatile int mWtfClusterCount;
13408
13409    /**
13410     * Write a description of an error (crash, WTF, ANR) to the drop box.
13411     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13412     * @param process which caused the error, null means the system server
13413     * @param activity which triggered the error, null if unknown
13414     * @param parent activity related to the error, null if unknown
13415     * @param subject line related to the error, null if absent
13416     * @param report in long form describing the error, null if absent
13417     * @param logFile to include in the report, null if none
13418     * @param crashInfo giving an application stack trace, null if absent
13419     */
13420    public void addErrorToDropBox(String eventType,
13421            ProcessRecord process, String processName, ActivityRecord activity,
13422            ActivityRecord parent, String subject,
13423            final String report, final File logFile,
13424            final ApplicationErrorReport.CrashInfo crashInfo) {
13425        // NOTE -- this must never acquire the ActivityManagerService lock,
13426        // otherwise the watchdog may be prevented from resetting the system.
13427
13428        final String dropboxTag = processClass(process) + "_" + eventType;
13429        final DropBoxManager dbox = (DropBoxManager)
13430                mContext.getSystemService(Context.DROPBOX_SERVICE);
13431
13432        // Exit early if the dropbox isn't configured to accept this report type.
13433        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13434
13435        // Rate-limit how often we're willing to do the heavy lifting below to
13436        // collect and record logs; currently 5 logs per 10 second period.
13437        final long now = SystemClock.elapsedRealtime();
13438        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13439            mWtfClusterStart = now;
13440            mWtfClusterCount = 1;
13441        } else {
13442            if (mWtfClusterCount++ >= 5) return;
13443        }
13444
13445        final StringBuilder sb = new StringBuilder(1024);
13446        appendDropBoxProcessHeaders(process, processName, sb);
13447        if (process != null) {
13448            sb.append("Foreground: ")
13449                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13450                    .append("\n");
13451        }
13452        if (activity != null) {
13453            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13454        }
13455        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13456            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13457        }
13458        if (parent != null && parent != activity) {
13459            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13460        }
13461        if (subject != null) {
13462            sb.append("Subject: ").append(subject).append("\n");
13463        }
13464        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13465        if (Debug.isDebuggerConnected()) {
13466            sb.append("Debugger: Connected\n");
13467        }
13468        sb.append("\n");
13469
13470        // Do the rest in a worker thread to avoid blocking the caller on I/O
13471        // (After this point, we shouldn't access AMS internal data structures.)
13472        Thread worker = new Thread("Error dump: " + dropboxTag) {
13473            @Override
13474            public void run() {
13475                if (report != null) {
13476                    sb.append(report);
13477                }
13478                if (logFile != null) {
13479                    try {
13480                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13481                                    "\n\n[[TRUNCATED]]"));
13482                    } catch (IOException e) {
13483                        Slog.e(TAG, "Error reading " + logFile, e);
13484                    }
13485                }
13486                if (crashInfo != null && crashInfo.stackTrace != null) {
13487                    sb.append(crashInfo.stackTrace);
13488                }
13489
13490                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13491                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13492                if (lines > 0) {
13493                    sb.append("\n");
13494
13495                    // Merge several logcat streams, and take the last N lines
13496                    InputStreamReader input = null;
13497                    try {
13498                        java.lang.Process logcat = new ProcessBuilder(
13499                                "/system/bin/timeout", "-k", "15s", "10s",
13500                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13501                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13502                                        .redirectErrorStream(true).start();
13503
13504                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13505                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13506                        input = new InputStreamReader(logcat.getInputStream());
13507
13508                        int num;
13509                        char[] buf = new char[8192];
13510                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13511                    } catch (IOException e) {
13512                        Slog.e(TAG, "Error running logcat", e);
13513                    } finally {
13514                        if (input != null) try { input.close(); } catch (IOException e) {}
13515                    }
13516                }
13517
13518                dbox.addText(dropboxTag, sb.toString());
13519            }
13520        };
13521
13522        if (process == null) {
13523            // If process is null, we are being called from some internal code
13524            // and may be about to die -- run this synchronously.
13525            worker.run();
13526        } else {
13527            worker.start();
13528        }
13529    }
13530
13531    @Override
13532    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13533        enforceNotIsolatedCaller("getProcessesInErrorState");
13534        // assume our apps are happy - lazy create the list
13535        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13536
13537        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13538                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13539        int userId = UserHandle.getUserId(Binder.getCallingUid());
13540
13541        synchronized (this) {
13542
13543            // iterate across all processes
13544            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13545                ProcessRecord app = mLruProcesses.get(i);
13546                if (!allUsers && app.userId != userId) {
13547                    continue;
13548                }
13549                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13550                    // This one's in trouble, so we'll generate a report for it
13551                    // crashes are higher priority (in case there's a crash *and* an anr)
13552                    ActivityManager.ProcessErrorStateInfo report = null;
13553                    if (app.crashing) {
13554                        report = app.crashingReport;
13555                    } else if (app.notResponding) {
13556                        report = app.notRespondingReport;
13557                    }
13558
13559                    if (report != null) {
13560                        if (errList == null) {
13561                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13562                        }
13563                        errList.add(report);
13564                    } else {
13565                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13566                                " crashing = " + app.crashing +
13567                                " notResponding = " + app.notResponding);
13568                    }
13569                }
13570            }
13571        }
13572
13573        return errList;
13574    }
13575
13576    static int procStateToImportance(int procState, int memAdj,
13577            ActivityManager.RunningAppProcessInfo currApp) {
13578        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13579        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13580            currApp.lru = memAdj;
13581        } else {
13582            currApp.lru = 0;
13583        }
13584        return imp;
13585    }
13586
13587    private void fillInProcMemInfo(ProcessRecord app,
13588            ActivityManager.RunningAppProcessInfo outInfo) {
13589        outInfo.pid = app.pid;
13590        outInfo.uid = app.info.uid;
13591        if (mHeavyWeightProcess == app) {
13592            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13593        }
13594        if (app.persistent) {
13595            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13596        }
13597        if (app.activities.size() > 0) {
13598            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13599        }
13600        outInfo.lastTrimLevel = app.trimMemoryLevel;
13601        int adj = app.curAdj;
13602        int procState = app.curProcState;
13603        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13604        outInfo.importanceReasonCode = app.adjTypeCode;
13605        outInfo.processState = app.curProcState;
13606    }
13607
13608    @Override
13609    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13610        enforceNotIsolatedCaller("getRunningAppProcesses");
13611
13612        final int callingUid = Binder.getCallingUid();
13613
13614        // Lazy instantiation of list
13615        List<ActivityManager.RunningAppProcessInfo> runList = null;
13616        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13617                callingUid) == PackageManager.PERMISSION_GRANTED;
13618        final int userId = UserHandle.getUserId(callingUid);
13619        final boolean allUids = isGetTasksAllowed(
13620                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13621
13622        synchronized (this) {
13623            // Iterate across all processes
13624            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13625                ProcessRecord app = mLruProcesses.get(i);
13626                if ((!allUsers && app.userId != userId)
13627                        || (!allUids && app.uid != callingUid)) {
13628                    continue;
13629                }
13630                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13631                    // Generate process state info for running application
13632                    ActivityManager.RunningAppProcessInfo currApp =
13633                        new ActivityManager.RunningAppProcessInfo(app.processName,
13634                                app.pid, app.getPackageList());
13635                    fillInProcMemInfo(app, currApp);
13636                    if (app.adjSource instanceof ProcessRecord) {
13637                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13638                        currApp.importanceReasonImportance =
13639                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13640                                        app.adjSourceProcState);
13641                    } else if (app.adjSource instanceof ActivityRecord) {
13642                        ActivityRecord r = (ActivityRecord)app.adjSource;
13643                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13644                    }
13645                    if (app.adjTarget instanceof ComponentName) {
13646                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13647                    }
13648                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13649                    //        + " lru=" + currApp.lru);
13650                    if (runList == null) {
13651                        runList = new ArrayList<>();
13652                    }
13653                    runList.add(currApp);
13654                }
13655            }
13656        }
13657        return runList;
13658    }
13659
13660    @Override
13661    public List<ApplicationInfo> getRunningExternalApplications() {
13662        enforceNotIsolatedCaller("getRunningExternalApplications");
13663        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13664        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13665        if (runningApps != null && runningApps.size() > 0) {
13666            Set<String> extList = new HashSet<String>();
13667            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13668                if (app.pkgList != null) {
13669                    for (String pkg : app.pkgList) {
13670                        extList.add(pkg);
13671                    }
13672                }
13673            }
13674            IPackageManager pm = AppGlobals.getPackageManager();
13675            for (String pkg : extList) {
13676                try {
13677                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13678                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13679                        retList.add(info);
13680                    }
13681                } catch (RemoteException e) {
13682                }
13683            }
13684        }
13685        return retList;
13686    }
13687
13688    @Override
13689    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13690        enforceNotIsolatedCaller("getMyMemoryState");
13691        synchronized (this) {
13692            ProcessRecord proc;
13693            synchronized (mPidsSelfLocked) {
13694                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13695            }
13696            fillInProcMemInfo(proc, outInfo);
13697        }
13698    }
13699
13700    @Override
13701    public int getMemoryTrimLevel() {
13702        enforceNotIsolatedCaller("getMyMemoryState");
13703        synchronized (this) {
13704            return mLastMemoryLevel;
13705        }
13706    }
13707
13708    @Override
13709    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13710            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13711        (new ActivityManagerShellCommand(this, false)).exec(
13712                this, in, out, err, args, resultReceiver);
13713    }
13714
13715    @Override
13716    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13717        if (checkCallingPermission(android.Manifest.permission.DUMP)
13718                != PackageManager.PERMISSION_GRANTED) {
13719            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13720                    + Binder.getCallingPid()
13721                    + ", uid=" + Binder.getCallingUid()
13722                    + " without permission "
13723                    + android.Manifest.permission.DUMP);
13724            return;
13725        }
13726
13727        boolean dumpAll = false;
13728        boolean dumpClient = false;
13729        String dumpPackage = null;
13730
13731        int opti = 0;
13732        while (opti < args.length) {
13733            String opt = args[opti];
13734            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13735                break;
13736            }
13737            opti++;
13738            if ("-a".equals(opt)) {
13739                dumpAll = true;
13740            } else if ("-c".equals(opt)) {
13741                dumpClient = true;
13742            } else if ("-p".equals(opt)) {
13743                if (opti < args.length) {
13744                    dumpPackage = args[opti];
13745                    opti++;
13746                } else {
13747                    pw.println("Error: -p option requires package argument");
13748                    return;
13749                }
13750                dumpClient = true;
13751            } else if ("-h".equals(opt)) {
13752                ActivityManagerShellCommand.dumpHelp(pw, true);
13753                return;
13754            } else {
13755                pw.println("Unknown argument: " + opt + "; use -h for help");
13756            }
13757        }
13758
13759        long origId = Binder.clearCallingIdentity();
13760        boolean more = false;
13761        // Is the caller requesting to dump a particular piece of data?
13762        if (opti < args.length) {
13763            String cmd = args[opti];
13764            opti++;
13765            if ("activities".equals(cmd) || "a".equals(cmd)) {
13766                synchronized (this) {
13767                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13768                }
13769            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13770                synchronized (this) {
13771                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13772                }
13773            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13774                String[] newArgs;
13775                String name;
13776                if (opti >= args.length) {
13777                    name = null;
13778                    newArgs = EMPTY_STRING_ARRAY;
13779                } else {
13780                    dumpPackage = args[opti];
13781                    opti++;
13782                    newArgs = new String[args.length - opti];
13783                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13784                            args.length - opti);
13785                }
13786                synchronized (this) {
13787                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13788                }
13789            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13790                String[] newArgs;
13791                String name;
13792                if (opti >= args.length) {
13793                    name = null;
13794                    newArgs = EMPTY_STRING_ARRAY;
13795                } else {
13796                    dumpPackage = args[opti];
13797                    opti++;
13798                    newArgs = new String[args.length - opti];
13799                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13800                            args.length - opti);
13801                }
13802                synchronized (this) {
13803                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13804                }
13805            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13806                String[] newArgs;
13807                String name;
13808                if (opti >= args.length) {
13809                    name = null;
13810                    newArgs = EMPTY_STRING_ARRAY;
13811                } else {
13812                    dumpPackage = args[opti];
13813                    opti++;
13814                    newArgs = new String[args.length - opti];
13815                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13816                            args.length - opti);
13817                }
13818                synchronized (this) {
13819                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13820                }
13821            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13822                synchronized (this) {
13823                    dumpOomLocked(fd, pw, args, opti, true);
13824                }
13825            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13826                synchronized (this) {
13827                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13828                }
13829            } else if ("provider".equals(cmd)) {
13830                String[] newArgs;
13831                String name;
13832                if (opti >= args.length) {
13833                    name = null;
13834                    newArgs = EMPTY_STRING_ARRAY;
13835                } else {
13836                    name = args[opti];
13837                    opti++;
13838                    newArgs = new String[args.length - opti];
13839                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13840                }
13841                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13842                    pw.println("No providers match: " + name);
13843                    pw.println("Use -h for help.");
13844                }
13845            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13846                synchronized (this) {
13847                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13848                }
13849            } else if ("service".equals(cmd)) {
13850                String[] newArgs;
13851                String name;
13852                if (opti >= args.length) {
13853                    name = null;
13854                    newArgs = EMPTY_STRING_ARRAY;
13855                } else {
13856                    name = args[opti];
13857                    opti++;
13858                    newArgs = new String[args.length - opti];
13859                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13860                            args.length - opti);
13861                }
13862                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13863                    pw.println("No services match: " + name);
13864                    pw.println("Use -h for help.");
13865                }
13866            } else if ("package".equals(cmd)) {
13867                String[] newArgs;
13868                if (opti >= args.length) {
13869                    pw.println("package: no package name specified");
13870                    pw.println("Use -h for help.");
13871                } else {
13872                    dumpPackage = args[opti];
13873                    opti++;
13874                    newArgs = new String[args.length - opti];
13875                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13876                            args.length - opti);
13877                    args = newArgs;
13878                    opti = 0;
13879                    more = true;
13880                }
13881            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13882                synchronized (this) {
13883                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13884                }
13885            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13886                if (dumpClient) {
13887                    ActiveServices.ServiceDumper dumper;
13888                    synchronized (this) {
13889                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
13890                                dumpPackage);
13891                    }
13892                    dumper.dumpWithClient();
13893                } else {
13894                    synchronized (this) {
13895                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
13896                                dumpPackage).dumpLocked();
13897                    }
13898                }
13899            } else if ("locks".equals(cmd)) {
13900                LockGuard.dump(fd, pw, args);
13901            } else {
13902                // Dumping a single activity?
13903                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13904                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13905                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13906                    if (res < 0) {
13907                        pw.println("Bad activity command, or no activities match: " + cmd);
13908                        pw.println("Use -h for help.");
13909                    }
13910                }
13911            }
13912            if (!more) {
13913                Binder.restoreCallingIdentity(origId);
13914                return;
13915            }
13916        }
13917
13918        // No piece of data specified, dump everything.
13919        if (dumpClient) {
13920            ActiveServices.ServiceDumper sdumper;
13921            synchronized (this) {
13922                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13923                pw.println();
13924                if (dumpAll) {
13925                    pw.println("-------------------------------------------------------------------------------");
13926                }
13927                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13928                pw.println();
13929                if (dumpAll) {
13930                    pw.println("-------------------------------------------------------------------------------");
13931                }
13932                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13933                pw.println();
13934                if (dumpAll) {
13935                    pw.println("-------------------------------------------------------------------------------");
13936                }
13937                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13938                pw.println();
13939                if (dumpAll) {
13940                    pw.println("-------------------------------------------------------------------------------");
13941                }
13942                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
13943                        dumpPackage);
13944            }
13945            sdumper.dumpWithClient();
13946            pw.println();
13947            synchronized (this) {
13948                if (dumpAll) {
13949                    pw.println("-------------------------------------------------------------------------------");
13950                }
13951                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13952                pw.println();
13953                if (dumpAll) {
13954                    pw.println("-------------------------------------------------------------------------------");
13955                }
13956                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13957                if (mAssociations.size() > 0) {
13958                    pw.println();
13959                    if (dumpAll) {
13960                        pw.println("-------------------------------------------------------------------------------");
13961                    }
13962                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13963                }
13964                pw.println();
13965                if (dumpAll) {
13966                    pw.println("-------------------------------------------------------------------------------");
13967                }
13968                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13969            }
13970
13971        } else {
13972            synchronized (this) {
13973                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13974                pw.println();
13975                if (dumpAll) {
13976                    pw.println("-------------------------------------------------------------------------------");
13977                }
13978                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13979                pw.println();
13980                if (dumpAll) {
13981                    pw.println("-------------------------------------------------------------------------------");
13982                }
13983                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13984                pw.println();
13985                if (dumpAll) {
13986                    pw.println("-------------------------------------------------------------------------------");
13987                }
13988                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13989                pw.println();
13990                if (dumpAll) {
13991                    pw.println("-------------------------------------------------------------------------------");
13992                }
13993                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
13994                        .dumpLocked();
13995                pw.println();
13996                if (dumpAll) {
13997                    pw.println("-------------------------------------------------------------------------------");
13998                }
13999                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14000                pw.println();
14001                if (dumpAll) {
14002                    pw.println("-------------------------------------------------------------------------------");
14003                }
14004                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14005                if (mAssociations.size() > 0) {
14006                    pw.println();
14007                    if (dumpAll) {
14008                        pw.println("-------------------------------------------------------------------------------");
14009                    }
14010                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14011                }
14012                pw.println();
14013                if (dumpAll) {
14014                    pw.println("-------------------------------------------------------------------------------");
14015                }
14016                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14017            }
14018        }
14019        Binder.restoreCallingIdentity(origId);
14020    }
14021
14022    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14023            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14024        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14025
14026        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14027                dumpPackage);
14028        boolean needSep = printedAnything;
14029
14030        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14031                dumpPackage, needSep, "  mFocusedActivity: ");
14032        if (printed) {
14033            printedAnything = true;
14034            needSep = false;
14035        }
14036
14037        if (dumpPackage == null) {
14038            if (needSep) {
14039                pw.println();
14040            }
14041            needSep = true;
14042            printedAnything = true;
14043            mStackSupervisor.dump(pw, "  ");
14044        }
14045
14046        if (!printedAnything) {
14047            pw.println("  (nothing)");
14048        }
14049    }
14050
14051    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14052            int opti, boolean dumpAll, String dumpPackage) {
14053        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14054
14055        boolean printedAnything = false;
14056
14057        if (mRecentTasks != null && mRecentTasks.size() > 0) {
14058            boolean printedHeader = false;
14059
14060            final int N = mRecentTasks.size();
14061            for (int i=0; i<N; i++) {
14062                TaskRecord tr = mRecentTasks.get(i);
14063                if (dumpPackage != null) {
14064                    if (tr.realActivity == null ||
14065                            !dumpPackage.equals(tr.realActivity)) {
14066                        continue;
14067                    }
14068                }
14069                if (!printedHeader) {
14070                    pw.println("  Recent tasks:");
14071                    printedHeader = true;
14072                    printedAnything = true;
14073                }
14074                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14075                        pw.println(tr);
14076                if (dumpAll) {
14077                    mRecentTasks.get(i).dump(pw, "    ");
14078                }
14079            }
14080        }
14081
14082        if (!printedAnything) {
14083            pw.println("  (nothing)");
14084        }
14085    }
14086
14087    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14088            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14089        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14090
14091        int dumpUid = 0;
14092        if (dumpPackage != null) {
14093            IPackageManager pm = AppGlobals.getPackageManager();
14094            try {
14095                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14096            } catch (RemoteException e) {
14097            }
14098        }
14099
14100        boolean printedAnything = false;
14101
14102        final long now = SystemClock.uptimeMillis();
14103
14104        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14105            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14106                    = mAssociations.valueAt(i1);
14107            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14108                SparseArray<ArrayMap<String, Association>> sourceUids
14109                        = targetComponents.valueAt(i2);
14110                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14111                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14112                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14113                        Association ass = sourceProcesses.valueAt(i4);
14114                        if (dumpPackage != null) {
14115                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14116                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14117                                continue;
14118                            }
14119                        }
14120                        printedAnything = true;
14121                        pw.print("  ");
14122                        pw.print(ass.mTargetProcess);
14123                        pw.print("/");
14124                        UserHandle.formatUid(pw, ass.mTargetUid);
14125                        pw.print(" <- ");
14126                        pw.print(ass.mSourceProcess);
14127                        pw.print("/");
14128                        UserHandle.formatUid(pw, ass.mSourceUid);
14129                        pw.println();
14130                        pw.print("    via ");
14131                        pw.print(ass.mTargetComponent.flattenToShortString());
14132                        pw.println();
14133                        pw.print("    ");
14134                        long dur = ass.mTime;
14135                        if (ass.mNesting > 0) {
14136                            dur += now - ass.mStartTime;
14137                        }
14138                        TimeUtils.formatDuration(dur, pw);
14139                        pw.print(" (");
14140                        pw.print(ass.mCount);
14141                        pw.print(" times)");
14142                        pw.print("  ");
14143                        for (int i=0; i<ass.mStateTimes.length; i++) {
14144                            long amt = ass.mStateTimes[i];
14145                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14146                                amt += now - ass.mLastStateUptime;
14147                            }
14148                            if (amt != 0) {
14149                                pw.print(" ");
14150                                pw.print(ProcessList.makeProcStateString(
14151                                            i + ActivityManager.MIN_PROCESS_STATE));
14152                                pw.print("=");
14153                                TimeUtils.formatDuration(amt, pw);
14154                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14155                                    pw.print("*");
14156                                }
14157                            }
14158                        }
14159                        pw.println();
14160                        if (ass.mNesting > 0) {
14161                            pw.print("    Currently active: ");
14162                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14163                            pw.println();
14164                        }
14165                    }
14166                }
14167            }
14168
14169        }
14170
14171        if (!printedAnything) {
14172            pw.println("  (nothing)");
14173        }
14174    }
14175
14176    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14177            String header, boolean needSep) {
14178        boolean printed = false;
14179        int whichAppId = -1;
14180        if (dumpPackage != null) {
14181            try {
14182                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14183                        dumpPackage, 0);
14184                whichAppId = UserHandle.getAppId(info.uid);
14185            } catch (NameNotFoundException e) {
14186                e.printStackTrace();
14187            }
14188        }
14189        for (int i=0; i<uids.size(); i++) {
14190            UidRecord uidRec = uids.valueAt(i);
14191            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14192                continue;
14193            }
14194            if (!printed) {
14195                printed = true;
14196                if (needSep) {
14197                    pw.println();
14198                }
14199                pw.print("  ");
14200                pw.println(header);
14201                needSep = true;
14202            }
14203            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14204            pw.print(": "); pw.println(uidRec);
14205        }
14206        return printed;
14207    }
14208
14209    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14210            int opti, boolean dumpAll, String dumpPackage) {
14211        boolean needSep = false;
14212        boolean printedAnything = false;
14213        int numPers = 0;
14214
14215        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14216
14217        if (dumpAll) {
14218            final int NP = mProcessNames.getMap().size();
14219            for (int ip=0; ip<NP; ip++) {
14220                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14221                final int NA = procs.size();
14222                for (int ia=0; ia<NA; ia++) {
14223                    ProcessRecord r = procs.valueAt(ia);
14224                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14225                        continue;
14226                    }
14227                    if (!needSep) {
14228                        pw.println("  All known processes:");
14229                        needSep = true;
14230                        printedAnything = true;
14231                    }
14232                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14233                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14234                        pw.print(" "); pw.println(r);
14235                    r.dump(pw, "    ");
14236                    if (r.persistent) {
14237                        numPers++;
14238                    }
14239                }
14240            }
14241        }
14242
14243        if (mIsolatedProcesses.size() > 0) {
14244            boolean printed = false;
14245            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14246                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14247                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14248                    continue;
14249                }
14250                if (!printed) {
14251                    if (needSep) {
14252                        pw.println();
14253                    }
14254                    pw.println("  Isolated process list (sorted by uid):");
14255                    printedAnything = true;
14256                    printed = true;
14257                    needSep = true;
14258                }
14259                pw.println(String.format("%sIsolated #%2d: %s",
14260                        "    ", i, r.toString()));
14261            }
14262        }
14263
14264        if (mActiveUids.size() > 0) {
14265            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14266                printedAnything = needSep = true;
14267            }
14268        }
14269        if (mValidateUids.size() > 0) {
14270            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14271                printedAnything = needSep = true;
14272            }
14273        }
14274
14275        if (mLruProcesses.size() > 0) {
14276            if (needSep) {
14277                pw.println();
14278            }
14279            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14280                    pw.print(" total, non-act at ");
14281                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14282                    pw.print(", non-svc at ");
14283                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14284                    pw.println("):");
14285            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14286            needSep = true;
14287            printedAnything = true;
14288        }
14289
14290        if (dumpAll || dumpPackage != null) {
14291            synchronized (mPidsSelfLocked) {
14292                boolean printed = false;
14293                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14294                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14295                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14296                        continue;
14297                    }
14298                    if (!printed) {
14299                        if (needSep) pw.println();
14300                        needSep = true;
14301                        pw.println("  PID mappings:");
14302                        printed = true;
14303                        printedAnything = true;
14304                    }
14305                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14306                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14307                }
14308            }
14309        }
14310
14311        if (mForegroundProcesses.size() > 0) {
14312            synchronized (mPidsSelfLocked) {
14313                boolean printed = false;
14314                for (int i=0; i<mForegroundProcesses.size(); i++) {
14315                    ProcessRecord r = mPidsSelfLocked.get(
14316                            mForegroundProcesses.valueAt(i).pid);
14317                    if (dumpPackage != null && (r == null
14318                            || !r.pkgList.containsKey(dumpPackage))) {
14319                        continue;
14320                    }
14321                    if (!printed) {
14322                        if (needSep) pw.println();
14323                        needSep = true;
14324                        pw.println("  Foreground Processes:");
14325                        printed = true;
14326                        printedAnything = true;
14327                    }
14328                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14329                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14330                }
14331            }
14332        }
14333
14334        if (mPersistentStartingProcesses.size() > 0) {
14335            if (needSep) pw.println();
14336            needSep = true;
14337            printedAnything = true;
14338            pw.println("  Persisent processes that are starting:");
14339            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14340                    "Starting Norm", "Restarting PERS", dumpPackage);
14341        }
14342
14343        if (mRemovedProcesses.size() > 0) {
14344            if (needSep) pw.println();
14345            needSep = true;
14346            printedAnything = true;
14347            pw.println("  Processes that are being removed:");
14348            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14349                    "Removed Norm", "Removed PERS", dumpPackage);
14350        }
14351
14352        if (mProcessesOnHold.size() > 0) {
14353            if (needSep) pw.println();
14354            needSep = true;
14355            printedAnything = true;
14356            pw.println("  Processes that are on old until the system is ready:");
14357            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14358                    "OnHold Norm", "OnHold PERS", dumpPackage);
14359        }
14360
14361        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14362
14363        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14364        if (needSep) {
14365            printedAnything = true;
14366        }
14367
14368        if (dumpPackage == null) {
14369            pw.println();
14370            needSep = false;
14371            mUserController.dump(pw, dumpAll);
14372        }
14373        if (mHomeProcess != null && (dumpPackage == null
14374                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14375            if (needSep) {
14376                pw.println();
14377                needSep = false;
14378            }
14379            pw.println("  mHomeProcess: " + mHomeProcess);
14380        }
14381        if (mPreviousProcess != null && (dumpPackage == null
14382                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14383            if (needSep) {
14384                pw.println();
14385                needSep = false;
14386            }
14387            pw.println("  mPreviousProcess: " + mPreviousProcess);
14388        }
14389        if (dumpAll) {
14390            StringBuilder sb = new StringBuilder(128);
14391            sb.append("  mPreviousProcessVisibleTime: ");
14392            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14393            pw.println(sb);
14394        }
14395        if (mHeavyWeightProcess != null && (dumpPackage == null
14396                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14397            if (needSep) {
14398                pw.println();
14399                needSep = false;
14400            }
14401            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14402        }
14403        if (dumpPackage == null) {
14404            pw.println("  mConfiguration: " + mConfiguration);
14405        }
14406        if (dumpAll) {
14407            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14408            if (mCompatModePackages.getPackages().size() > 0) {
14409                boolean printed = false;
14410                for (Map.Entry<String, Integer> entry
14411                        : mCompatModePackages.getPackages().entrySet()) {
14412                    String pkg = entry.getKey();
14413                    int mode = entry.getValue();
14414                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14415                        continue;
14416                    }
14417                    if (!printed) {
14418                        pw.println("  mScreenCompatPackages:");
14419                        printed = true;
14420                    }
14421                    pw.print("    "); pw.print(pkg); pw.print(": ");
14422                            pw.print(mode); pw.println();
14423                }
14424            }
14425        }
14426        if (dumpPackage == null) {
14427            pw.println("  mWakefulness="
14428                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14429            pw.println("  mSleepTokens=" + mSleepTokens);
14430            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14431                    + lockScreenShownToString());
14432            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14433            if (mRunningVoice != null) {
14434                pw.println("  mRunningVoice=" + mRunningVoice);
14435                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14436            }
14437        }
14438        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14439                || mOrigWaitForDebugger) {
14440            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14441                    || dumpPackage.equals(mOrigDebugApp)) {
14442                if (needSep) {
14443                    pw.println();
14444                    needSep = false;
14445                }
14446                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14447                        + " mDebugTransient=" + mDebugTransient
14448                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14449            }
14450        }
14451        if (mCurAppTimeTracker != null) {
14452            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14453        }
14454        if (mMemWatchProcesses.getMap().size() > 0) {
14455            pw.println("  Mem watch processes:");
14456            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14457                    = mMemWatchProcesses.getMap();
14458            for (int i=0; i<procs.size(); i++) {
14459                final String proc = procs.keyAt(i);
14460                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14461                for (int j=0; j<uids.size(); j++) {
14462                    if (needSep) {
14463                        pw.println();
14464                        needSep = false;
14465                    }
14466                    StringBuilder sb = new StringBuilder();
14467                    sb.append("    ").append(proc).append('/');
14468                    UserHandle.formatUid(sb, uids.keyAt(j));
14469                    Pair<Long, String> val = uids.valueAt(j);
14470                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14471                    if (val.second != null) {
14472                        sb.append(", report to ").append(val.second);
14473                    }
14474                    pw.println(sb.toString());
14475                }
14476            }
14477            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14478            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14479            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14480                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14481        }
14482        if (mTrackAllocationApp != null) {
14483            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14484                if (needSep) {
14485                    pw.println();
14486                    needSep = false;
14487                }
14488                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14489            }
14490        }
14491        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14492                || mProfileFd != null) {
14493            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14494                if (needSep) {
14495                    pw.println();
14496                    needSep = false;
14497                }
14498                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14499                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14500                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14501                        + mAutoStopProfiler);
14502                pw.println("  mProfileType=" + mProfileType);
14503            }
14504        }
14505        if (mNativeDebuggingApp != null) {
14506            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14507                if (needSep) {
14508                    pw.println();
14509                    needSep = false;
14510                }
14511                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14512            }
14513        }
14514        if (dumpPackage == null) {
14515            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14516                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14517                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14518            }
14519            if (mController != null) {
14520                pw.println("  mController=" + mController
14521                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14522            }
14523            if (dumpAll) {
14524                pw.println("  Total persistent processes: " + numPers);
14525                pw.println("  mProcessesReady=" + mProcessesReady
14526                        + " mSystemReady=" + mSystemReady
14527                        + " mBooted=" + mBooted
14528                        + " mFactoryTest=" + mFactoryTest);
14529                pw.println("  mBooting=" + mBooting
14530                        + " mCallFinishBooting=" + mCallFinishBooting
14531                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14532                pw.print("  mLastPowerCheckRealtime=");
14533                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14534                        pw.println("");
14535                pw.print("  mLastPowerCheckUptime=");
14536                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14537                        pw.println("");
14538                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14539                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14540                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14541                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14542                        + " (" + mLruProcesses.size() + " total)"
14543                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14544                        + " mNumServiceProcs=" + mNumServiceProcs
14545                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14546                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14547                        + " mLastMemoryLevel=" + mLastMemoryLevel
14548                        + " mLastNumProcesses=" + mLastNumProcesses);
14549                long now = SystemClock.uptimeMillis();
14550                pw.print("  mLastIdleTime=");
14551                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14552                        pw.print(" mLowRamSinceLastIdle=");
14553                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14554                        pw.println();
14555            }
14556        }
14557
14558        if (!printedAnything) {
14559            pw.println("  (nothing)");
14560        }
14561    }
14562
14563    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14564            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14565        if (mProcessesToGc.size() > 0) {
14566            boolean printed = false;
14567            long now = SystemClock.uptimeMillis();
14568            for (int i=0; i<mProcessesToGc.size(); i++) {
14569                ProcessRecord proc = mProcessesToGc.get(i);
14570                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14571                    continue;
14572                }
14573                if (!printed) {
14574                    if (needSep) pw.println();
14575                    needSep = true;
14576                    pw.println("  Processes that are waiting to GC:");
14577                    printed = true;
14578                }
14579                pw.print("    Process "); pw.println(proc);
14580                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14581                        pw.print(", last gced=");
14582                        pw.print(now-proc.lastRequestedGc);
14583                        pw.print(" ms ago, last lowMem=");
14584                        pw.print(now-proc.lastLowMemory);
14585                        pw.println(" ms ago");
14586
14587            }
14588        }
14589        return needSep;
14590    }
14591
14592    void printOomLevel(PrintWriter pw, String name, int adj) {
14593        pw.print("    ");
14594        if (adj >= 0) {
14595            pw.print(' ');
14596            if (adj < 10) pw.print(' ');
14597        } else {
14598            if (adj > -10) pw.print(' ');
14599        }
14600        pw.print(adj);
14601        pw.print(": ");
14602        pw.print(name);
14603        pw.print(" (");
14604        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14605        pw.println(")");
14606    }
14607
14608    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14609            int opti, boolean dumpAll) {
14610        boolean needSep = false;
14611
14612        if (mLruProcesses.size() > 0) {
14613            if (needSep) pw.println();
14614            needSep = true;
14615            pw.println("  OOM levels:");
14616            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14617            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14618            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14619            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14620            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14621            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14622            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14623            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14624            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14625            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14626            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14627            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14628            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14629            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14630
14631            if (needSep) pw.println();
14632            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14633                    pw.print(" total, non-act at ");
14634                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14635                    pw.print(", non-svc at ");
14636                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14637                    pw.println("):");
14638            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14639            needSep = true;
14640        }
14641
14642        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14643
14644        pw.println();
14645        pw.println("  mHomeProcess: " + mHomeProcess);
14646        pw.println("  mPreviousProcess: " + mPreviousProcess);
14647        if (mHeavyWeightProcess != null) {
14648            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14649        }
14650
14651        return true;
14652    }
14653
14654    /**
14655     * There are three ways to call this:
14656     *  - no provider specified: dump all the providers
14657     *  - a flattened component name that matched an existing provider was specified as the
14658     *    first arg: dump that one provider
14659     *  - the first arg isn't the flattened component name of an existing provider:
14660     *    dump all providers whose component contains the first arg as a substring
14661     */
14662    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14663            int opti, boolean dumpAll) {
14664        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14665    }
14666
14667    static class ItemMatcher {
14668        ArrayList<ComponentName> components;
14669        ArrayList<String> strings;
14670        ArrayList<Integer> objects;
14671        boolean all;
14672
14673        ItemMatcher() {
14674            all = true;
14675        }
14676
14677        void build(String name) {
14678            ComponentName componentName = ComponentName.unflattenFromString(name);
14679            if (componentName != null) {
14680                if (components == null) {
14681                    components = new ArrayList<ComponentName>();
14682                }
14683                components.add(componentName);
14684                all = false;
14685            } else {
14686                int objectId = 0;
14687                // Not a '/' separated full component name; maybe an object ID?
14688                try {
14689                    objectId = Integer.parseInt(name, 16);
14690                    if (objects == null) {
14691                        objects = new ArrayList<Integer>();
14692                    }
14693                    objects.add(objectId);
14694                    all = false;
14695                } catch (RuntimeException e) {
14696                    // Not an integer; just do string match.
14697                    if (strings == null) {
14698                        strings = new ArrayList<String>();
14699                    }
14700                    strings.add(name);
14701                    all = false;
14702                }
14703            }
14704        }
14705
14706        int build(String[] args, int opti) {
14707            for (; opti<args.length; opti++) {
14708                String name = args[opti];
14709                if ("--".equals(name)) {
14710                    return opti+1;
14711                }
14712                build(name);
14713            }
14714            return opti;
14715        }
14716
14717        boolean match(Object object, ComponentName comp) {
14718            if (all) {
14719                return true;
14720            }
14721            if (components != null) {
14722                for (int i=0; i<components.size(); i++) {
14723                    if (components.get(i).equals(comp)) {
14724                        return true;
14725                    }
14726                }
14727            }
14728            if (objects != null) {
14729                for (int i=0; i<objects.size(); i++) {
14730                    if (System.identityHashCode(object) == objects.get(i)) {
14731                        return true;
14732                    }
14733                }
14734            }
14735            if (strings != null) {
14736                String flat = comp.flattenToString();
14737                for (int i=0; i<strings.size(); i++) {
14738                    if (flat.contains(strings.get(i))) {
14739                        return true;
14740                    }
14741                }
14742            }
14743            return false;
14744        }
14745    }
14746
14747    /**
14748     * There are three things that cmd can be:
14749     *  - a flattened component name that matches an existing activity
14750     *  - the cmd arg isn't the flattened component name of an existing activity:
14751     *    dump all activity whose component contains the cmd as a substring
14752     *  - A hex number of the ActivityRecord object instance.
14753     */
14754    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14755            int opti, boolean dumpAll) {
14756        ArrayList<ActivityRecord> activities;
14757
14758        synchronized (this) {
14759            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14760        }
14761
14762        if (activities.size() <= 0) {
14763            return false;
14764        }
14765
14766        String[] newArgs = new String[args.length - opti];
14767        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14768
14769        TaskRecord lastTask = null;
14770        boolean needSep = false;
14771        for (int i=activities.size()-1; i>=0; i--) {
14772            ActivityRecord r = activities.get(i);
14773            if (needSep) {
14774                pw.println();
14775            }
14776            needSep = true;
14777            synchronized (this) {
14778                if (lastTask != r.task) {
14779                    lastTask = r.task;
14780                    pw.print("TASK "); pw.print(lastTask.affinity);
14781                            pw.print(" id="); pw.println(lastTask.taskId);
14782                    if (dumpAll) {
14783                        lastTask.dump(pw, "  ");
14784                    }
14785                }
14786            }
14787            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14788        }
14789        return true;
14790    }
14791
14792    /**
14793     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14794     * there is a thread associated with the activity.
14795     */
14796    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14797            final ActivityRecord r, String[] args, boolean dumpAll) {
14798        String innerPrefix = prefix + "  ";
14799        synchronized (this) {
14800            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14801                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14802                    pw.print(" pid=");
14803                    if (r.app != null) pw.println(r.app.pid);
14804                    else pw.println("(not running)");
14805            if (dumpAll) {
14806                r.dump(pw, innerPrefix);
14807            }
14808        }
14809        if (r.app != null && r.app.thread != null) {
14810            // flush anything that is already in the PrintWriter since the thread is going
14811            // to write to the file descriptor directly
14812            pw.flush();
14813            try {
14814                TransferPipe tp = new TransferPipe();
14815                try {
14816                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14817                            r.appToken, innerPrefix, args);
14818                    tp.go(fd);
14819                } finally {
14820                    tp.kill();
14821                }
14822            } catch (IOException e) {
14823                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14824            } catch (RemoteException e) {
14825                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14826            }
14827        }
14828    }
14829
14830    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14831            int opti, boolean dumpAll, String dumpPackage) {
14832        boolean needSep = false;
14833        boolean onlyHistory = false;
14834        boolean printedAnything = false;
14835
14836        if ("history".equals(dumpPackage)) {
14837            if (opti < args.length && "-s".equals(args[opti])) {
14838                dumpAll = false;
14839            }
14840            onlyHistory = true;
14841            dumpPackage = null;
14842        }
14843
14844        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14845        if (!onlyHistory && dumpAll) {
14846            if (mRegisteredReceivers.size() > 0) {
14847                boolean printed = false;
14848                Iterator it = mRegisteredReceivers.values().iterator();
14849                while (it.hasNext()) {
14850                    ReceiverList r = (ReceiverList)it.next();
14851                    if (dumpPackage != null && (r.app == null ||
14852                            !dumpPackage.equals(r.app.info.packageName))) {
14853                        continue;
14854                    }
14855                    if (!printed) {
14856                        pw.println("  Registered Receivers:");
14857                        needSep = true;
14858                        printed = true;
14859                        printedAnything = true;
14860                    }
14861                    pw.print("  * "); pw.println(r);
14862                    r.dump(pw, "    ");
14863                }
14864            }
14865
14866            if (mReceiverResolver.dump(pw, needSep ?
14867                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14868                    "    ", dumpPackage, false, false)) {
14869                needSep = true;
14870                printedAnything = true;
14871            }
14872        }
14873
14874        for (BroadcastQueue q : mBroadcastQueues) {
14875            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14876            printedAnything |= needSep;
14877        }
14878
14879        needSep = true;
14880
14881        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14882            for (int user=0; user<mStickyBroadcasts.size(); user++) {
14883                if (needSep) {
14884                    pw.println();
14885                }
14886                needSep = true;
14887                printedAnything = true;
14888                pw.print("  Sticky broadcasts for user ");
14889                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14890                StringBuilder sb = new StringBuilder(128);
14891                for (Map.Entry<String, ArrayList<Intent>> ent
14892                        : mStickyBroadcasts.valueAt(user).entrySet()) {
14893                    pw.print("  * Sticky action "); pw.print(ent.getKey());
14894                    if (dumpAll) {
14895                        pw.println(":");
14896                        ArrayList<Intent> intents = ent.getValue();
14897                        final int N = intents.size();
14898                        for (int i=0; i<N; i++) {
14899                            sb.setLength(0);
14900                            sb.append("    Intent: ");
14901                            intents.get(i).toShortString(sb, false, true, false, false);
14902                            pw.println(sb.toString());
14903                            Bundle bundle = intents.get(i).getExtras();
14904                            if (bundle != null) {
14905                                pw.print("      ");
14906                                pw.println(bundle.toString());
14907                            }
14908                        }
14909                    } else {
14910                        pw.println("");
14911                    }
14912                }
14913            }
14914        }
14915
14916        if (!onlyHistory && dumpAll) {
14917            pw.println();
14918            for (BroadcastQueue queue : mBroadcastQueues) {
14919                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14920                        + queue.mBroadcastsScheduled);
14921            }
14922            pw.println("  mHandler:");
14923            mHandler.dump(new PrintWriterPrinter(pw), "    ");
14924            needSep = true;
14925            printedAnything = true;
14926        }
14927
14928        if (!printedAnything) {
14929            pw.println("  (nothing)");
14930        }
14931    }
14932
14933    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14934            int opti, boolean dumpAll, String dumpPackage) {
14935        boolean needSep;
14936        boolean printedAnything = false;
14937
14938        ItemMatcher matcher = new ItemMatcher();
14939        matcher.build(args, opti);
14940
14941        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14942
14943        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14944        printedAnything |= needSep;
14945
14946        if (mLaunchingProviders.size() > 0) {
14947            boolean printed = false;
14948            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14949                ContentProviderRecord r = mLaunchingProviders.get(i);
14950                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14951                    continue;
14952                }
14953                if (!printed) {
14954                    if (needSep) pw.println();
14955                    needSep = true;
14956                    pw.println("  Launching content providers:");
14957                    printed = true;
14958                    printedAnything = true;
14959                }
14960                pw.print("  Launching #"); pw.print(i); pw.print(": ");
14961                        pw.println(r);
14962            }
14963        }
14964
14965        if (!printedAnything) {
14966            pw.println("  (nothing)");
14967        }
14968    }
14969
14970    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14971            int opti, boolean dumpAll, String dumpPackage) {
14972        boolean needSep = false;
14973        boolean printedAnything = false;
14974
14975        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14976
14977        if (mGrantedUriPermissions.size() > 0) {
14978            boolean printed = false;
14979            int dumpUid = -2;
14980            if (dumpPackage != null) {
14981                try {
14982                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
14983                            MATCH_UNINSTALLED_PACKAGES, 0);
14984                } catch (NameNotFoundException e) {
14985                    dumpUid = -1;
14986                }
14987            }
14988            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14989                int uid = mGrantedUriPermissions.keyAt(i);
14990                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14991                    continue;
14992                }
14993                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14994                if (!printed) {
14995                    if (needSep) pw.println();
14996                    needSep = true;
14997                    pw.println("  Granted Uri Permissions:");
14998                    printed = true;
14999                    printedAnything = true;
15000                }
15001                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15002                for (UriPermission perm : perms.values()) {
15003                    pw.print("    "); pw.println(perm);
15004                    if (dumpAll) {
15005                        perm.dump(pw, "      ");
15006                    }
15007                }
15008            }
15009        }
15010
15011        if (!printedAnything) {
15012            pw.println("  (nothing)");
15013        }
15014    }
15015
15016    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15017            int opti, boolean dumpAll, String dumpPackage) {
15018        boolean printed = false;
15019
15020        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15021
15022        if (mIntentSenderRecords.size() > 0) {
15023            Iterator<WeakReference<PendingIntentRecord>> it
15024                    = mIntentSenderRecords.values().iterator();
15025            while (it.hasNext()) {
15026                WeakReference<PendingIntentRecord> ref = it.next();
15027                PendingIntentRecord rec = ref != null ? ref.get(): null;
15028                if (dumpPackage != null && (rec == null
15029                        || !dumpPackage.equals(rec.key.packageName))) {
15030                    continue;
15031                }
15032                printed = true;
15033                if (rec != null) {
15034                    pw.print("  * "); pw.println(rec);
15035                    if (dumpAll) {
15036                        rec.dump(pw, "    ");
15037                    }
15038                } else {
15039                    pw.print("  * "); pw.println(ref);
15040                }
15041            }
15042        }
15043
15044        if (!printed) {
15045            pw.println("  (nothing)");
15046        }
15047    }
15048
15049    private static final int dumpProcessList(PrintWriter pw,
15050            ActivityManagerService service, List list,
15051            String prefix, String normalLabel, String persistentLabel,
15052            String dumpPackage) {
15053        int numPers = 0;
15054        final int N = list.size()-1;
15055        for (int i=N; i>=0; i--) {
15056            ProcessRecord r = (ProcessRecord)list.get(i);
15057            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15058                continue;
15059            }
15060            pw.println(String.format("%s%s #%2d: %s",
15061                    prefix, (r.persistent ? persistentLabel : normalLabel),
15062                    i, r.toString()));
15063            if (r.persistent) {
15064                numPers++;
15065            }
15066        }
15067        return numPers;
15068    }
15069
15070    private static final boolean dumpProcessOomList(PrintWriter pw,
15071            ActivityManagerService service, List<ProcessRecord> origList,
15072            String prefix, String normalLabel, String persistentLabel,
15073            boolean inclDetails, String dumpPackage) {
15074
15075        ArrayList<Pair<ProcessRecord, Integer>> list
15076                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15077        for (int i=0; i<origList.size(); i++) {
15078            ProcessRecord r = origList.get(i);
15079            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15080                continue;
15081            }
15082            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15083        }
15084
15085        if (list.size() <= 0) {
15086            return false;
15087        }
15088
15089        Comparator<Pair<ProcessRecord, Integer>> comparator
15090                = new Comparator<Pair<ProcessRecord, Integer>>() {
15091            @Override
15092            public int compare(Pair<ProcessRecord, Integer> object1,
15093                    Pair<ProcessRecord, Integer> object2) {
15094                if (object1.first.setAdj != object2.first.setAdj) {
15095                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15096                }
15097                if (object1.first.setProcState != object2.first.setProcState) {
15098                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15099                }
15100                if (object1.second.intValue() != object2.second.intValue()) {
15101                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15102                }
15103                return 0;
15104            }
15105        };
15106
15107        Collections.sort(list, comparator);
15108
15109        final long curRealtime = SystemClock.elapsedRealtime();
15110        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15111        final long curUptime = SystemClock.uptimeMillis();
15112        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15113
15114        for (int i=list.size()-1; i>=0; i--) {
15115            ProcessRecord r = list.get(i).first;
15116            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15117            char schedGroup;
15118            switch (r.setSchedGroup) {
15119                case ProcessList.SCHED_GROUP_BACKGROUND:
15120                    schedGroup = 'B';
15121                    break;
15122                case ProcessList.SCHED_GROUP_DEFAULT:
15123                    schedGroup = 'F';
15124                    break;
15125                case ProcessList.SCHED_GROUP_TOP_APP:
15126                    schedGroup = 'T';
15127                    break;
15128                default:
15129                    schedGroup = '?';
15130                    break;
15131            }
15132            char foreground;
15133            if (r.foregroundActivities) {
15134                foreground = 'A';
15135            } else if (r.foregroundServices) {
15136                foreground = 'S';
15137            } else {
15138                foreground = ' ';
15139            }
15140            String procState = ProcessList.makeProcStateString(r.curProcState);
15141            pw.print(prefix);
15142            pw.print(r.persistent ? persistentLabel : normalLabel);
15143            pw.print(" #");
15144            int num = (origList.size()-1)-list.get(i).second;
15145            if (num < 10) pw.print(' ');
15146            pw.print(num);
15147            pw.print(": ");
15148            pw.print(oomAdj);
15149            pw.print(' ');
15150            pw.print(schedGroup);
15151            pw.print('/');
15152            pw.print(foreground);
15153            pw.print('/');
15154            pw.print(procState);
15155            pw.print(" trm:");
15156            if (r.trimMemoryLevel < 10) pw.print(' ');
15157            pw.print(r.trimMemoryLevel);
15158            pw.print(' ');
15159            pw.print(r.toShortString());
15160            pw.print(" (");
15161            pw.print(r.adjType);
15162            pw.println(')');
15163            if (r.adjSource != null || r.adjTarget != null) {
15164                pw.print(prefix);
15165                pw.print("    ");
15166                if (r.adjTarget instanceof ComponentName) {
15167                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15168                } else if (r.adjTarget != null) {
15169                    pw.print(r.adjTarget.toString());
15170                } else {
15171                    pw.print("{null}");
15172                }
15173                pw.print("<=");
15174                if (r.adjSource instanceof ProcessRecord) {
15175                    pw.print("Proc{");
15176                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15177                    pw.println("}");
15178                } else if (r.adjSource != null) {
15179                    pw.println(r.adjSource.toString());
15180                } else {
15181                    pw.println("{null}");
15182                }
15183            }
15184            if (inclDetails) {
15185                pw.print(prefix);
15186                pw.print("    ");
15187                pw.print("oom: max="); pw.print(r.maxAdj);
15188                pw.print(" curRaw="); pw.print(r.curRawAdj);
15189                pw.print(" setRaw="); pw.print(r.setRawAdj);
15190                pw.print(" cur="); pw.print(r.curAdj);
15191                pw.print(" set="); pw.println(r.setAdj);
15192                pw.print(prefix);
15193                pw.print("    ");
15194                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15195                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15196                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15197                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15198                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15199                pw.println();
15200                pw.print(prefix);
15201                pw.print("    ");
15202                pw.print("cached="); pw.print(r.cached);
15203                pw.print(" empty="); pw.print(r.empty);
15204                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15205
15206                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15207                    if (r.lastWakeTime != 0) {
15208                        long wtime;
15209                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15210                        synchronized (stats) {
15211                            wtime = stats.getProcessWakeTime(r.info.uid,
15212                                    r.pid, curRealtime);
15213                        }
15214                        long timeUsed = wtime - r.lastWakeTime;
15215                        pw.print(prefix);
15216                        pw.print("    ");
15217                        pw.print("keep awake over ");
15218                        TimeUtils.formatDuration(realtimeSince, pw);
15219                        pw.print(" used ");
15220                        TimeUtils.formatDuration(timeUsed, pw);
15221                        pw.print(" (");
15222                        pw.print((timeUsed*100)/realtimeSince);
15223                        pw.println("%)");
15224                    }
15225                    if (r.lastCpuTime != 0) {
15226                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15227                        pw.print(prefix);
15228                        pw.print("    ");
15229                        pw.print("run cpu over ");
15230                        TimeUtils.formatDuration(uptimeSince, pw);
15231                        pw.print(" used ");
15232                        TimeUtils.formatDuration(timeUsed, pw);
15233                        pw.print(" (");
15234                        pw.print((timeUsed*100)/uptimeSince);
15235                        pw.println("%)");
15236                    }
15237                }
15238            }
15239        }
15240        return true;
15241    }
15242
15243    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15244            String[] args) {
15245        ArrayList<ProcessRecord> procs;
15246        synchronized (this) {
15247            if (args != null && args.length > start
15248                    && args[start].charAt(0) != '-') {
15249                procs = new ArrayList<ProcessRecord>();
15250                int pid = -1;
15251                try {
15252                    pid = Integer.parseInt(args[start]);
15253                } catch (NumberFormatException e) {
15254                }
15255                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15256                    ProcessRecord proc = mLruProcesses.get(i);
15257                    if (proc.pid == pid) {
15258                        procs.add(proc);
15259                    } else if (allPkgs && proc.pkgList != null
15260                            && proc.pkgList.containsKey(args[start])) {
15261                        procs.add(proc);
15262                    } else if (proc.processName.equals(args[start])) {
15263                        procs.add(proc);
15264                    }
15265                }
15266                if (procs.size() <= 0) {
15267                    return null;
15268                }
15269            } else {
15270                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15271            }
15272        }
15273        return procs;
15274    }
15275
15276    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15277            PrintWriter pw, String[] args) {
15278        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15279        if (procs == null) {
15280            pw.println("No process found for: " + args[0]);
15281            return;
15282        }
15283
15284        long uptime = SystemClock.uptimeMillis();
15285        long realtime = SystemClock.elapsedRealtime();
15286        pw.println("Applications Graphics Acceleration Info:");
15287        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15288
15289        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15290            ProcessRecord r = procs.get(i);
15291            if (r.thread != null) {
15292                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15293                pw.flush();
15294                try {
15295                    TransferPipe tp = new TransferPipe();
15296                    try {
15297                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15298                        tp.go(fd);
15299                    } finally {
15300                        tp.kill();
15301                    }
15302                } catch (IOException e) {
15303                    pw.println("Failure while dumping the app: " + r);
15304                    pw.flush();
15305                } catch (RemoteException e) {
15306                    pw.println("Got a RemoteException while dumping the app " + r);
15307                    pw.flush();
15308                }
15309            }
15310        }
15311    }
15312
15313    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15314        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15315        if (procs == null) {
15316            pw.println("No process found for: " + args[0]);
15317            return;
15318        }
15319
15320        pw.println("Applications Database Info:");
15321
15322        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15323            ProcessRecord r = procs.get(i);
15324            if (r.thread != null) {
15325                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15326                pw.flush();
15327                try {
15328                    TransferPipe tp = new TransferPipe();
15329                    try {
15330                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15331                        tp.go(fd);
15332                    } finally {
15333                        tp.kill();
15334                    }
15335                } catch (IOException e) {
15336                    pw.println("Failure while dumping the app: " + r);
15337                    pw.flush();
15338                } catch (RemoteException e) {
15339                    pw.println("Got a RemoteException while dumping the app " + r);
15340                    pw.flush();
15341                }
15342            }
15343        }
15344    }
15345
15346    final static class MemItem {
15347        final boolean isProc;
15348        final String label;
15349        final String shortLabel;
15350        final long pss;
15351        final long swapPss;
15352        final int id;
15353        final boolean hasActivities;
15354        ArrayList<MemItem> subitems;
15355
15356        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15357                boolean _hasActivities) {
15358            isProc = true;
15359            label = _label;
15360            shortLabel = _shortLabel;
15361            pss = _pss;
15362            swapPss = _swapPss;
15363            id = _id;
15364            hasActivities = _hasActivities;
15365        }
15366
15367        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15368            isProc = false;
15369            label = _label;
15370            shortLabel = _shortLabel;
15371            pss = _pss;
15372            swapPss = _swapPss;
15373            id = _id;
15374            hasActivities = false;
15375        }
15376    }
15377
15378    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15379            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15380        if (sort && !isCompact) {
15381            Collections.sort(items, new Comparator<MemItem>() {
15382                @Override
15383                public int compare(MemItem lhs, MemItem rhs) {
15384                    if (lhs.pss < rhs.pss) {
15385                        return 1;
15386                    } else if (lhs.pss > rhs.pss) {
15387                        return -1;
15388                    }
15389                    return 0;
15390                }
15391            });
15392        }
15393
15394        for (int i=0; i<items.size(); i++) {
15395            MemItem mi = items.get(i);
15396            if (!isCompact) {
15397                if (dumpSwapPss) {
15398                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15399                            mi.label, stringifyKBSize(mi.swapPss));
15400                } else {
15401                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15402                }
15403            } else if (mi.isProc) {
15404                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15405                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15406                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15407                pw.println(mi.hasActivities ? ",a" : ",e");
15408            } else {
15409                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15410                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15411            }
15412            if (mi.subitems != null) {
15413                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15414                        true, isCompact, dumpSwapPss);
15415            }
15416        }
15417    }
15418
15419    // These are in KB.
15420    static final long[] DUMP_MEM_BUCKETS = new long[] {
15421        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15422        120*1024, 160*1024, 200*1024,
15423        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15424        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15425    };
15426
15427    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15428            boolean stackLike) {
15429        int start = label.lastIndexOf('.');
15430        if (start >= 0) start++;
15431        else start = 0;
15432        int end = label.length();
15433        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15434            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15435                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15436                out.append(bucket);
15437                out.append(stackLike ? "MB." : "MB ");
15438                out.append(label, start, end);
15439                return;
15440            }
15441        }
15442        out.append(memKB/1024);
15443        out.append(stackLike ? "MB." : "MB ");
15444        out.append(label, start, end);
15445    }
15446
15447    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15448            ProcessList.NATIVE_ADJ,
15449            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15450            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15451            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15452            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15453            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15454            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15455    };
15456    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15457            "Native",
15458            "System", "Persistent", "Persistent Service", "Foreground",
15459            "Visible", "Perceptible",
15460            "Heavy Weight", "Backup",
15461            "A Services", "Home",
15462            "Previous", "B Services", "Cached"
15463    };
15464    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15465            "native",
15466            "sys", "pers", "persvc", "fore",
15467            "vis", "percept",
15468            "heavy", "backup",
15469            "servicea", "home",
15470            "prev", "serviceb", "cached"
15471    };
15472
15473    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15474            long realtime, boolean isCheckinRequest, boolean isCompact) {
15475        if (isCompact) {
15476            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15477        }
15478        if (isCheckinRequest || isCompact) {
15479            // short checkin version
15480            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15481        } else {
15482            pw.println("Applications Memory Usage (in Kilobytes):");
15483            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15484        }
15485    }
15486
15487    private static final int KSM_SHARED = 0;
15488    private static final int KSM_SHARING = 1;
15489    private static final int KSM_UNSHARED = 2;
15490    private static final int KSM_VOLATILE = 3;
15491
15492    private final long[] getKsmInfo() {
15493        long[] longOut = new long[4];
15494        final int[] SINGLE_LONG_FORMAT = new int[] {
15495            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15496        };
15497        long[] longTmp = new long[1];
15498        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15499                SINGLE_LONG_FORMAT, null, longTmp, null);
15500        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15501        longTmp[0] = 0;
15502        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15503                SINGLE_LONG_FORMAT, null, longTmp, null);
15504        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15505        longTmp[0] = 0;
15506        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15507                SINGLE_LONG_FORMAT, null, longTmp, null);
15508        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15509        longTmp[0] = 0;
15510        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15511                SINGLE_LONG_FORMAT, null, longTmp, null);
15512        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15513        return longOut;
15514    }
15515
15516    private static String stringifySize(long size, int order) {
15517        Locale locale = Locale.US;
15518        switch (order) {
15519            case 1:
15520                return String.format(locale, "%,13d", size);
15521            case 1024:
15522                return String.format(locale, "%,9dK", size / 1024);
15523            case 1024 * 1024:
15524                return String.format(locale, "%,5dM", size / 1024 / 1024);
15525            case 1024 * 1024 * 1024:
15526                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15527            default:
15528                throw new IllegalArgumentException("Invalid size order");
15529        }
15530    }
15531
15532    private static String stringifyKBSize(long size) {
15533        return stringifySize(size * 1024, 1024);
15534    }
15535
15536    // Update this version number in case you change the 'compact' format
15537    private static final int MEMINFO_COMPACT_VERSION = 1;
15538
15539    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15540            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15541        boolean dumpDetails = false;
15542        boolean dumpFullDetails = false;
15543        boolean dumpDalvik = false;
15544        boolean dumpSummaryOnly = false;
15545        boolean dumpUnreachable = false;
15546        boolean oomOnly = false;
15547        boolean isCompact = false;
15548        boolean localOnly = false;
15549        boolean packages = false;
15550        boolean isCheckinRequest = false;
15551        boolean dumpSwapPss = false;
15552
15553        int opti = 0;
15554        while (opti < args.length) {
15555            String opt = args[opti];
15556            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15557                break;
15558            }
15559            opti++;
15560            if ("-a".equals(opt)) {
15561                dumpDetails = true;
15562                dumpFullDetails = true;
15563                dumpDalvik = true;
15564                dumpSwapPss = true;
15565            } else if ("-d".equals(opt)) {
15566                dumpDalvik = true;
15567            } else if ("-c".equals(opt)) {
15568                isCompact = true;
15569            } else if ("-s".equals(opt)) {
15570                dumpDetails = true;
15571                dumpSummaryOnly = true;
15572            } else if ("-S".equals(opt)) {
15573                dumpSwapPss = true;
15574            } else if ("--unreachable".equals(opt)) {
15575                dumpUnreachable = true;
15576            } else if ("--oom".equals(opt)) {
15577                oomOnly = true;
15578            } else if ("--local".equals(opt)) {
15579                localOnly = true;
15580            } else if ("--package".equals(opt)) {
15581                packages = true;
15582            } else if ("--checkin".equals(opt)) {
15583                isCheckinRequest = true;
15584
15585            } else if ("-h".equals(opt)) {
15586                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15587                pw.println("  -a: include all available information for each process.");
15588                pw.println("  -d: include dalvik details.");
15589                pw.println("  -c: dump in a compact machine-parseable representation.");
15590                pw.println("  -s: dump only summary of application memory usage.");
15591                pw.println("  -S: dump also SwapPss.");
15592                pw.println("  --oom: only show processes organized by oom adj.");
15593                pw.println("  --local: only collect details locally, don't call process.");
15594                pw.println("  --package: interpret process arg as package, dumping all");
15595                pw.println("             processes that have loaded that package.");
15596                pw.println("  --checkin: dump data for a checkin");
15597                pw.println("If [process] is specified it can be the name or ");
15598                pw.println("pid of a specific process to dump.");
15599                return;
15600            } else {
15601                pw.println("Unknown argument: " + opt + "; use -h for help");
15602            }
15603        }
15604
15605        long uptime = SystemClock.uptimeMillis();
15606        long realtime = SystemClock.elapsedRealtime();
15607        final long[] tmpLong = new long[1];
15608
15609        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15610        if (procs == null) {
15611            // No Java processes.  Maybe they want to print a native process.
15612            if (args != null && args.length > opti
15613                    && args[opti].charAt(0) != '-') {
15614                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15615                        = new ArrayList<ProcessCpuTracker.Stats>();
15616                updateCpuStatsNow();
15617                int findPid = -1;
15618                try {
15619                    findPid = Integer.parseInt(args[opti]);
15620                } catch (NumberFormatException e) {
15621                }
15622                synchronized (mProcessCpuTracker) {
15623                    final int N = mProcessCpuTracker.countStats();
15624                    for (int i=0; i<N; i++) {
15625                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15626                        if (st.pid == findPid || (st.baseName != null
15627                                && st.baseName.equals(args[opti]))) {
15628                            nativeProcs.add(st);
15629                        }
15630                    }
15631                }
15632                if (nativeProcs.size() > 0) {
15633                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15634                            isCompact);
15635                    Debug.MemoryInfo mi = null;
15636                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15637                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15638                        final int pid = r.pid;
15639                        if (!isCheckinRequest && dumpDetails) {
15640                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15641                        }
15642                        if (mi == null) {
15643                            mi = new Debug.MemoryInfo();
15644                        }
15645                        if (dumpDetails || (!brief && !oomOnly)) {
15646                            Debug.getMemoryInfo(pid, mi);
15647                        } else {
15648                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15649                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15650                        }
15651                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15652                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15653                        if (isCheckinRequest) {
15654                            pw.println();
15655                        }
15656                    }
15657                    return;
15658                }
15659            }
15660            pw.println("No process found for: " + args[opti]);
15661            return;
15662        }
15663
15664        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15665            dumpDetails = true;
15666        }
15667
15668        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15669
15670        String[] innerArgs = new String[args.length-opti];
15671        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15672
15673        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15674        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15675        long nativePss = 0;
15676        long nativeSwapPss = 0;
15677        long dalvikPss = 0;
15678        long dalvikSwapPss = 0;
15679        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15680                EmptyArray.LONG;
15681        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15682                EmptyArray.LONG;
15683        long otherPss = 0;
15684        long otherSwapPss = 0;
15685        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15686        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15687
15688        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15689        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15690        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15691                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15692
15693        long totalPss = 0;
15694        long totalSwapPss = 0;
15695        long cachedPss = 0;
15696        long cachedSwapPss = 0;
15697        boolean hasSwapPss = false;
15698
15699        Debug.MemoryInfo mi = null;
15700        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15701            final ProcessRecord r = procs.get(i);
15702            final IApplicationThread thread;
15703            final int pid;
15704            final int oomAdj;
15705            final boolean hasActivities;
15706            synchronized (this) {
15707                thread = r.thread;
15708                pid = r.pid;
15709                oomAdj = r.getSetAdjWithServices();
15710                hasActivities = r.activities.size() > 0;
15711            }
15712            if (thread != null) {
15713                if (!isCheckinRequest && dumpDetails) {
15714                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15715                }
15716                if (mi == null) {
15717                    mi = new Debug.MemoryInfo();
15718                }
15719                if (dumpDetails || (!brief && !oomOnly)) {
15720                    Debug.getMemoryInfo(pid, mi);
15721                    hasSwapPss = mi.hasSwappedOutPss;
15722                } else {
15723                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15724                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15725                }
15726                if (dumpDetails) {
15727                    if (localOnly) {
15728                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15729                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15730                        if (isCheckinRequest) {
15731                            pw.println();
15732                        }
15733                    } else {
15734                        try {
15735                            pw.flush();
15736                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15737                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15738                        } catch (RemoteException e) {
15739                            if (!isCheckinRequest) {
15740                                pw.println("Got RemoteException!");
15741                                pw.flush();
15742                            }
15743                        }
15744                    }
15745                }
15746
15747                final long myTotalPss = mi.getTotalPss();
15748                final long myTotalUss = mi.getTotalUss();
15749                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15750
15751                synchronized (this) {
15752                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15753                        // Record this for posterity if the process has been stable.
15754                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15755                    }
15756                }
15757
15758                if (!isCheckinRequest && mi != null) {
15759                    totalPss += myTotalPss;
15760                    totalSwapPss += myTotalSwapPss;
15761                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15762                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15763                            myTotalSwapPss, pid, hasActivities);
15764                    procMems.add(pssItem);
15765                    procMemsMap.put(pid, pssItem);
15766
15767                    nativePss += mi.nativePss;
15768                    nativeSwapPss += mi.nativeSwappedOutPss;
15769                    dalvikPss += mi.dalvikPss;
15770                    dalvikSwapPss += mi.dalvikSwappedOutPss;
15771                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15772                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15773                        dalvikSubitemSwapPss[j] +=
15774                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15775                    }
15776                    otherPss += mi.otherPss;
15777                    otherSwapPss += mi.otherSwappedOutPss;
15778                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15779                        long mem = mi.getOtherPss(j);
15780                        miscPss[j] += mem;
15781                        otherPss -= mem;
15782                        mem = mi.getOtherSwappedOutPss(j);
15783                        miscSwapPss[j] += mem;
15784                        otherSwapPss -= mem;
15785                    }
15786
15787                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15788                        cachedPss += myTotalPss;
15789                        cachedSwapPss += myTotalSwapPss;
15790                    }
15791
15792                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15793                        if (oomIndex == (oomPss.length - 1)
15794                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
15795                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
15796                            oomPss[oomIndex] += myTotalPss;
15797                            oomSwapPss[oomIndex] += myTotalSwapPss;
15798                            if (oomProcs[oomIndex] == null) {
15799                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15800                            }
15801                            oomProcs[oomIndex].add(pssItem);
15802                            break;
15803                        }
15804                    }
15805                }
15806            }
15807        }
15808
15809        long nativeProcTotalPss = 0;
15810
15811        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15812            // If we are showing aggregations, also look for native processes to
15813            // include so that our aggregations are more accurate.
15814            updateCpuStatsNow();
15815            mi = null;
15816            synchronized (mProcessCpuTracker) {
15817                final int N = mProcessCpuTracker.countStats();
15818                for (int i=0; i<N; i++) {
15819                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15820                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15821                        if (mi == null) {
15822                            mi = new Debug.MemoryInfo();
15823                        }
15824                        if (!brief && !oomOnly) {
15825                            Debug.getMemoryInfo(st.pid, mi);
15826                        } else {
15827                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15828                            mi.nativePrivateDirty = (int)tmpLong[0];
15829                        }
15830
15831                        final long myTotalPss = mi.getTotalPss();
15832                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15833                        totalPss += myTotalPss;
15834                        nativeProcTotalPss += myTotalPss;
15835
15836                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15837                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
15838                        procMems.add(pssItem);
15839
15840                        nativePss += mi.nativePss;
15841                        nativeSwapPss += mi.nativeSwappedOutPss;
15842                        dalvikPss += mi.dalvikPss;
15843                        dalvikSwapPss += mi.dalvikSwappedOutPss;
15844                        for (int j=0; j<dalvikSubitemPss.length; j++) {
15845                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15846                            dalvikSubitemSwapPss[j] +=
15847                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15848                        }
15849                        otherPss += mi.otherPss;
15850                        otherSwapPss += mi.otherSwappedOutPss;
15851                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15852                            long mem = mi.getOtherPss(j);
15853                            miscPss[j] += mem;
15854                            otherPss -= mem;
15855                            mem = mi.getOtherSwappedOutPss(j);
15856                            miscSwapPss[j] += mem;
15857                            otherSwapPss -= mem;
15858                        }
15859                        oomPss[0] += myTotalPss;
15860                        oomSwapPss[0] += myTotalSwapPss;
15861                        if (oomProcs[0] == null) {
15862                            oomProcs[0] = new ArrayList<MemItem>();
15863                        }
15864                        oomProcs[0].add(pssItem);
15865                    }
15866                }
15867            }
15868
15869            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15870
15871            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
15872            final MemItem dalvikItem =
15873                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
15874            if (dalvikSubitemPss.length > 0) {
15875                dalvikItem.subitems = new ArrayList<MemItem>();
15876                for (int j=0; j<dalvikSubitemPss.length; j++) {
15877                    final String name = Debug.MemoryInfo.getOtherLabel(
15878                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
15879                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
15880                                    dalvikSubitemSwapPss[j], j));
15881                }
15882            }
15883            catMems.add(dalvikItem);
15884            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
15885            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15886                String label = Debug.MemoryInfo.getOtherLabel(j);
15887                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
15888            }
15889
15890            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15891            for (int j=0; j<oomPss.length; j++) {
15892                if (oomPss[j] != 0) {
15893                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15894                            : DUMP_MEM_OOM_LABEL[j];
15895                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
15896                            DUMP_MEM_OOM_ADJ[j]);
15897                    item.subitems = oomProcs[j];
15898                    oomMems.add(item);
15899                }
15900            }
15901
15902            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
15903            if (!brief && !oomOnly && !isCompact) {
15904                pw.println();
15905                pw.println("Total PSS by process:");
15906                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
15907                pw.println();
15908            }
15909            if (!isCompact) {
15910                pw.println("Total PSS by OOM adjustment:");
15911            }
15912            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
15913            if (!brief && !oomOnly) {
15914                PrintWriter out = categoryPw != null ? categoryPw : pw;
15915                if (!isCompact) {
15916                    out.println();
15917                    out.println("Total PSS by category:");
15918                }
15919                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
15920            }
15921            if (!isCompact) {
15922                pw.println();
15923            }
15924            MemInfoReader memInfo = new MemInfoReader();
15925            memInfo.readMemInfo();
15926            if (nativeProcTotalPss > 0) {
15927                synchronized (this) {
15928                    final long cachedKb = memInfo.getCachedSizeKb();
15929                    final long freeKb = memInfo.getFreeSizeKb();
15930                    final long zramKb = memInfo.getZramTotalSizeKb();
15931                    final long kernelKb = memInfo.getKernelUsedSizeKb();
15932                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15933                            kernelKb*1024, nativeProcTotalPss*1024);
15934                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15935                            nativeProcTotalPss);
15936                }
15937            }
15938            if (!brief) {
15939                if (!isCompact) {
15940                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15941                    pw.print(" (status ");
15942                    switch (mLastMemoryLevel) {
15943                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15944                            pw.println("normal)");
15945                            break;
15946                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15947                            pw.println("moderate)");
15948                            break;
15949                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
15950                            pw.println("low)");
15951                            break;
15952                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15953                            pw.println("critical)");
15954                            break;
15955                        default:
15956                            pw.print(mLastMemoryLevel);
15957                            pw.println(")");
15958                            break;
15959                    }
15960                    pw.print(" Free RAM: ");
15961                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15962                            + memInfo.getFreeSizeKb()));
15963                    pw.print(" (");
15964                    pw.print(stringifyKBSize(cachedPss));
15965                    pw.print(" cached pss + ");
15966                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
15967                    pw.print(" cached kernel + ");
15968                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
15969                    pw.println(" free)");
15970                } else {
15971                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15972                    pw.print(cachedPss + memInfo.getCachedSizeKb()
15973                            + memInfo.getFreeSizeKb()); pw.print(",");
15974                    pw.println(totalPss - cachedPss);
15975                }
15976            }
15977            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
15978                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15979                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
15980            if (!isCompact) {
15981                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
15982                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
15983                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
15984                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
15985                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
15986            } else {
15987                pw.print("lostram,"); pw.println(lostRAM);
15988            }
15989            if (!brief) {
15990                if (memInfo.getZramTotalSizeKb() != 0) {
15991                    if (!isCompact) {
15992                        pw.print("     ZRAM: ");
15993                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
15994                                pw.print(" physical used for ");
15995                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
15996                                        - memInfo.getSwapFreeSizeKb()));
15997                                pw.print(" in swap (");
15998                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
15999                                pw.println(" total swap)");
16000                    } else {
16001                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16002                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16003                                pw.println(memInfo.getSwapFreeSizeKb());
16004                    }
16005                }
16006                final long[] ksm = getKsmInfo();
16007                if (!isCompact) {
16008                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16009                            || ksm[KSM_VOLATILE] != 0) {
16010                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16011                                pw.print(" saved from shared ");
16012                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16013                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16014                                pw.print(" unshared; ");
16015                                pw.print(stringifyKBSize(
16016                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
16017                    }
16018                    pw.print("   Tuning: ");
16019                    pw.print(ActivityManager.staticGetMemoryClass());
16020                    pw.print(" (large ");
16021                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16022                    pw.print("), oom ");
16023                    pw.print(stringifySize(
16024                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16025                    pw.print(", restore limit ");
16026                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16027                    if (ActivityManager.isLowRamDeviceStatic()) {
16028                        pw.print(" (low-ram)");
16029                    }
16030                    if (ActivityManager.isHighEndGfx()) {
16031                        pw.print(" (high-end-gfx)");
16032                    }
16033                    pw.println();
16034                } else {
16035                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16036                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16037                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16038                    pw.print("tuning,");
16039                    pw.print(ActivityManager.staticGetMemoryClass());
16040                    pw.print(',');
16041                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16042                    pw.print(',');
16043                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16044                    if (ActivityManager.isLowRamDeviceStatic()) {
16045                        pw.print(",low-ram");
16046                    }
16047                    if (ActivityManager.isHighEndGfx()) {
16048                        pw.print(",high-end-gfx");
16049                    }
16050                    pw.println();
16051                }
16052            }
16053        }
16054    }
16055
16056    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16057            long memtrack, String name) {
16058        sb.append("  ");
16059        sb.append(ProcessList.makeOomAdjString(oomAdj));
16060        sb.append(' ');
16061        sb.append(ProcessList.makeProcStateString(procState));
16062        sb.append(' ');
16063        ProcessList.appendRamKb(sb, pss);
16064        sb.append(": ");
16065        sb.append(name);
16066        if (memtrack > 0) {
16067            sb.append(" (");
16068            sb.append(stringifyKBSize(memtrack));
16069            sb.append(" memtrack)");
16070        }
16071    }
16072
16073    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16074        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16075        sb.append(" (pid ");
16076        sb.append(mi.pid);
16077        sb.append(") ");
16078        sb.append(mi.adjType);
16079        sb.append('\n');
16080        if (mi.adjReason != null) {
16081            sb.append("                      ");
16082            sb.append(mi.adjReason);
16083            sb.append('\n');
16084        }
16085    }
16086
16087    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16088        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16089        for (int i=0, N=memInfos.size(); i<N; i++) {
16090            ProcessMemInfo mi = memInfos.get(i);
16091            infoMap.put(mi.pid, mi);
16092        }
16093        updateCpuStatsNow();
16094        long[] memtrackTmp = new long[1];
16095        synchronized (mProcessCpuTracker) {
16096            final int N = mProcessCpuTracker.countStats();
16097            for (int i=0; i<N; i++) {
16098                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16099                if (st.vsize > 0) {
16100                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
16101                    if (pss > 0) {
16102                        if (infoMap.indexOfKey(st.pid) < 0) {
16103                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16104                                    ProcessList.NATIVE_ADJ, -1, "native", null);
16105                            mi.pss = pss;
16106                            mi.memtrack = memtrackTmp[0];
16107                            memInfos.add(mi);
16108                        }
16109                    }
16110                }
16111            }
16112        }
16113
16114        long totalPss = 0;
16115        long totalMemtrack = 0;
16116        for (int i=0, N=memInfos.size(); i<N; i++) {
16117            ProcessMemInfo mi = memInfos.get(i);
16118            if (mi.pss == 0) {
16119                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16120                mi.memtrack = memtrackTmp[0];
16121            }
16122            totalPss += mi.pss;
16123            totalMemtrack += mi.memtrack;
16124        }
16125        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16126            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16127                if (lhs.oomAdj != rhs.oomAdj) {
16128                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16129                }
16130                if (lhs.pss != rhs.pss) {
16131                    return lhs.pss < rhs.pss ? 1 : -1;
16132                }
16133                return 0;
16134            }
16135        });
16136
16137        StringBuilder tag = new StringBuilder(128);
16138        StringBuilder stack = new StringBuilder(128);
16139        tag.append("Low on memory -- ");
16140        appendMemBucket(tag, totalPss, "total", false);
16141        appendMemBucket(stack, totalPss, "total", true);
16142
16143        StringBuilder fullNativeBuilder = new StringBuilder(1024);
16144        StringBuilder shortNativeBuilder = new StringBuilder(1024);
16145        StringBuilder fullJavaBuilder = new StringBuilder(1024);
16146
16147        boolean firstLine = true;
16148        int lastOomAdj = Integer.MIN_VALUE;
16149        long extraNativeRam = 0;
16150        long extraNativeMemtrack = 0;
16151        long cachedPss = 0;
16152        for (int i=0, N=memInfos.size(); i<N; i++) {
16153            ProcessMemInfo mi = memInfos.get(i);
16154
16155            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16156                cachedPss += mi.pss;
16157            }
16158
16159            if (mi.oomAdj != ProcessList.NATIVE_ADJ
16160                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
16161                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
16162                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16163                if (lastOomAdj != mi.oomAdj) {
16164                    lastOomAdj = mi.oomAdj;
16165                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16166                        tag.append(" / ");
16167                    }
16168                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16169                        if (firstLine) {
16170                            stack.append(":");
16171                            firstLine = false;
16172                        }
16173                        stack.append("\n\t at ");
16174                    } else {
16175                        stack.append("$");
16176                    }
16177                } else {
16178                    tag.append(" ");
16179                    stack.append("$");
16180                }
16181                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16182                    appendMemBucket(tag, mi.pss, mi.name, false);
16183                }
16184                appendMemBucket(stack, mi.pss, mi.name, true);
16185                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16186                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16187                    stack.append("(");
16188                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16189                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16190                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16191                            stack.append(":");
16192                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16193                        }
16194                    }
16195                    stack.append(")");
16196                }
16197            }
16198
16199            appendMemInfo(fullNativeBuilder, mi);
16200            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16201                // The short form only has native processes that are >= 512K.
16202                if (mi.pss >= 512) {
16203                    appendMemInfo(shortNativeBuilder, mi);
16204                } else {
16205                    extraNativeRam += mi.pss;
16206                    extraNativeMemtrack += mi.memtrack;
16207                }
16208            } else {
16209                // Short form has all other details, but if we have collected RAM
16210                // from smaller native processes let's dump a summary of that.
16211                if (extraNativeRam > 0) {
16212                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16213                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16214                    shortNativeBuilder.append('\n');
16215                    extraNativeRam = 0;
16216                }
16217                appendMemInfo(fullJavaBuilder, mi);
16218            }
16219        }
16220
16221        fullJavaBuilder.append("           ");
16222        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16223        fullJavaBuilder.append(": TOTAL");
16224        if (totalMemtrack > 0) {
16225            fullJavaBuilder.append(" (");
16226            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16227            fullJavaBuilder.append(" memtrack)");
16228        } else {
16229        }
16230        fullJavaBuilder.append("\n");
16231
16232        MemInfoReader memInfo = new MemInfoReader();
16233        memInfo.readMemInfo();
16234        final long[] infos = memInfo.getRawInfo();
16235
16236        StringBuilder memInfoBuilder = new StringBuilder(1024);
16237        Debug.getMemInfo(infos);
16238        memInfoBuilder.append("  MemInfo: ");
16239        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16240        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16241        memInfoBuilder.append(stringifyKBSize(
16242                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16243        memInfoBuilder.append(stringifyKBSize(
16244                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16245        memInfoBuilder.append(stringifyKBSize(
16246                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16247        memInfoBuilder.append("           ");
16248        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16249        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16250        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16251        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16252        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16253            memInfoBuilder.append("  ZRAM: ");
16254            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16255            memInfoBuilder.append(" RAM, ");
16256            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16257            memInfoBuilder.append(" swap total, ");
16258            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16259            memInfoBuilder.append(" swap free\n");
16260        }
16261        final long[] ksm = getKsmInfo();
16262        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16263                || ksm[KSM_VOLATILE] != 0) {
16264            memInfoBuilder.append("  KSM: ");
16265            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16266            memInfoBuilder.append(" saved from shared ");
16267            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16268            memInfoBuilder.append("\n       ");
16269            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16270            memInfoBuilder.append(" unshared; ");
16271            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16272            memInfoBuilder.append(" volatile\n");
16273        }
16274        memInfoBuilder.append("  Free RAM: ");
16275        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16276                + memInfo.getFreeSizeKb()));
16277        memInfoBuilder.append("\n");
16278        memInfoBuilder.append("  Used RAM: ");
16279        memInfoBuilder.append(stringifyKBSize(
16280                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16281        memInfoBuilder.append("\n");
16282        memInfoBuilder.append("  Lost RAM: ");
16283        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16284                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16285                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16286        memInfoBuilder.append("\n");
16287        Slog.i(TAG, "Low on memory:");
16288        Slog.i(TAG, shortNativeBuilder.toString());
16289        Slog.i(TAG, fullJavaBuilder.toString());
16290        Slog.i(TAG, memInfoBuilder.toString());
16291
16292        StringBuilder dropBuilder = new StringBuilder(1024);
16293        /*
16294        StringWriter oomSw = new StringWriter();
16295        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16296        StringWriter catSw = new StringWriter();
16297        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16298        String[] emptyArgs = new String[] { };
16299        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16300        oomPw.flush();
16301        String oomString = oomSw.toString();
16302        */
16303        dropBuilder.append("Low on memory:");
16304        dropBuilder.append(stack);
16305        dropBuilder.append('\n');
16306        dropBuilder.append(fullNativeBuilder);
16307        dropBuilder.append(fullJavaBuilder);
16308        dropBuilder.append('\n');
16309        dropBuilder.append(memInfoBuilder);
16310        dropBuilder.append('\n');
16311        /*
16312        dropBuilder.append(oomString);
16313        dropBuilder.append('\n');
16314        */
16315        StringWriter catSw = new StringWriter();
16316        synchronized (ActivityManagerService.this) {
16317            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16318            String[] emptyArgs = new String[] { };
16319            catPw.println();
16320            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16321            catPw.println();
16322            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16323                    false, null).dumpLocked();
16324            catPw.println();
16325            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16326            catPw.flush();
16327        }
16328        dropBuilder.append(catSw.toString());
16329        addErrorToDropBox("lowmem", null, "system_server", null,
16330                null, tag.toString(), dropBuilder.toString(), null, null);
16331        //Slog.i(TAG, "Sent to dropbox:");
16332        //Slog.i(TAG, dropBuilder.toString());
16333        synchronized (ActivityManagerService.this) {
16334            long now = SystemClock.uptimeMillis();
16335            if (mLastMemUsageReportTime < now) {
16336                mLastMemUsageReportTime = now;
16337            }
16338        }
16339    }
16340
16341    /**
16342     * Searches array of arguments for the specified string
16343     * @param args array of argument strings
16344     * @param value value to search for
16345     * @return true if the value is contained in the array
16346     */
16347    private static boolean scanArgs(String[] args, String value) {
16348        if (args != null) {
16349            for (String arg : args) {
16350                if (value.equals(arg)) {
16351                    return true;
16352                }
16353            }
16354        }
16355        return false;
16356    }
16357
16358    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16359            ContentProviderRecord cpr, boolean always) {
16360        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16361
16362        if (!inLaunching || always) {
16363            synchronized (cpr) {
16364                cpr.launchingApp = null;
16365                cpr.notifyAll();
16366            }
16367            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16368            String names[] = cpr.info.authority.split(";");
16369            for (int j = 0; j < names.length; j++) {
16370                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16371            }
16372        }
16373
16374        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16375            ContentProviderConnection conn = cpr.connections.get(i);
16376            if (conn.waiting) {
16377                // If this connection is waiting for the provider, then we don't
16378                // need to mess with its process unless we are always removing
16379                // or for some reason the provider is not currently launching.
16380                if (inLaunching && !always) {
16381                    continue;
16382                }
16383            }
16384            ProcessRecord capp = conn.client;
16385            conn.dead = true;
16386            if (conn.stableCount > 0) {
16387                if (!capp.persistent && capp.thread != null
16388                        && capp.pid != 0
16389                        && capp.pid != MY_PID) {
16390                    capp.kill("depends on provider "
16391                            + cpr.name.flattenToShortString()
16392                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
16393                }
16394            } else if (capp.thread != null && conn.provider.provider != null) {
16395                try {
16396                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16397                } catch (RemoteException e) {
16398                }
16399                // In the protocol here, we don't expect the client to correctly
16400                // clean up this connection, we'll just remove it.
16401                cpr.connections.remove(i);
16402                if (conn.client.conProviders.remove(conn)) {
16403                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16404                }
16405            }
16406        }
16407
16408        if (inLaunching && always) {
16409            mLaunchingProviders.remove(cpr);
16410        }
16411        return inLaunching;
16412    }
16413
16414    /**
16415     * Main code for cleaning up a process when it has gone away.  This is
16416     * called both as a result of the process dying, or directly when stopping
16417     * a process when running in single process mode.
16418     *
16419     * @return Returns true if the given process has been restarted, so the
16420     * app that was passed in must remain on the process lists.
16421     */
16422    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16423            boolean restarting, boolean allowRestart, int index) {
16424        if (index >= 0) {
16425            removeLruProcessLocked(app);
16426            ProcessList.remove(app.pid);
16427        }
16428
16429        mProcessesToGc.remove(app);
16430        mPendingPssProcesses.remove(app);
16431
16432        // Dismiss any open dialogs.
16433        if (app.crashDialog != null && !app.forceCrashReport) {
16434            app.crashDialog.dismiss();
16435            app.crashDialog = null;
16436        }
16437        if (app.anrDialog != null) {
16438            app.anrDialog.dismiss();
16439            app.anrDialog = null;
16440        }
16441        if (app.waitDialog != null) {
16442            app.waitDialog.dismiss();
16443            app.waitDialog = null;
16444        }
16445
16446        app.crashing = false;
16447        app.notResponding = false;
16448
16449        app.resetPackageList(mProcessStats);
16450        app.unlinkDeathRecipient();
16451        app.makeInactive(mProcessStats);
16452        app.waitingToKill = null;
16453        app.forcingToForeground = null;
16454        updateProcessForegroundLocked(app, false, false);
16455        app.foregroundActivities = false;
16456        app.hasShownUi = false;
16457        app.treatLikeActivity = false;
16458        app.hasAboveClient = false;
16459        app.hasClientActivities = false;
16460
16461        mServices.killServicesLocked(app, allowRestart);
16462
16463        boolean restart = false;
16464
16465        // Remove published content providers.
16466        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16467            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16468            final boolean always = app.bad || !allowRestart;
16469            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16470            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16471                // We left the provider in the launching list, need to
16472                // restart it.
16473                restart = true;
16474            }
16475
16476            cpr.provider = null;
16477            cpr.proc = null;
16478        }
16479        app.pubProviders.clear();
16480
16481        // Take care of any launching providers waiting for this process.
16482        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16483            restart = true;
16484        }
16485
16486        // Unregister from connected content providers.
16487        if (!app.conProviders.isEmpty()) {
16488            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16489                ContentProviderConnection conn = app.conProviders.get(i);
16490                conn.provider.connections.remove(conn);
16491                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16492                        conn.provider.name);
16493            }
16494            app.conProviders.clear();
16495        }
16496
16497        // At this point there may be remaining entries in mLaunchingProviders
16498        // where we were the only one waiting, so they are no longer of use.
16499        // Look for these and clean up if found.
16500        // XXX Commented out for now.  Trying to figure out a way to reproduce
16501        // the actual situation to identify what is actually going on.
16502        if (false) {
16503            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16504                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16505                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16506                    synchronized (cpr) {
16507                        cpr.launchingApp = null;
16508                        cpr.notifyAll();
16509                    }
16510                }
16511            }
16512        }
16513
16514        skipCurrentReceiverLocked(app);
16515
16516        // Unregister any receivers.
16517        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16518            removeReceiverLocked(app.receivers.valueAt(i));
16519        }
16520        app.receivers.clear();
16521
16522        // If the app is undergoing backup, tell the backup manager about it
16523        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16524            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16525                    + mBackupTarget.appInfo + " died during backup");
16526            try {
16527                IBackupManager bm = IBackupManager.Stub.asInterface(
16528                        ServiceManager.getService(Context.BACKUP_SERVICE));
16529                bm.agentDisconnected(app.info.packageName);
16530            } catch (RemoteException e) {
16531                // can't happen; backup manager is local
16532            }
16533        }
16534
16535        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16536            ProcessChangeItem item = mPendingProcessChanges.get(i);
16537            if (item.pid == app.pid) {
16538                mPendingProcessChanges.remove(i);
16539                mAvailProcessChanges.add(item);
16540            }
16541        }
16542        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16543                null).sendToTarget();
16544
16545        // If the caller is restarting this app, then leave it in its
16546        // current lists and let the caller take care of it.
16547        if (restarting) {
16548            return false;
16549        }
16550
16551        if (!app.persistent || app.isolated) {
16552            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16553                    "Removing non-persistent process during cleanup: " + app);
16554            removeProcessNameLocked(app.processName, app.uid);
16555            if (mHeavyWeightProcess == app) {
16556                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16557                        mHeavyWeightProcess.userId, 0));
16558                mHeavyWeightProcess = null;
16559            }
16560        } else if (!app.removed) {
16561            // This app is persistent, so we need to keep its record around.
16562            // If it is not already on the pending app list, add it there
16563            // and start a new process for it.
16564            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16565                mPersistentStartingProcesses.add(app);
16566                restart = true;
16567            }
16568        }
16569        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16570                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16571        mProcessesOnHold.remove(app);
16572
16573        if (app == mHomeProcess) {
16574            mHomeProcess = null;
16575        }
16576        if (app == mPreviousProcess) {
16577            mPreviousProcess = null;
16578        }
16579
16580        if (restart && !app.isolated) {
16581            // We have components that still need to be running in the
16582            // process, so re-launch it.
16583            if (index < 0) {
16584                ProcessList.remove(app.pid);
16585            }
16586            addProcessNameLocked(app);
16587            startProcessLocked(app, "restart", app.processName);
16588            return true;
16589        } else if (app.pid > 0 && app.pid != MY_PID) {
16590            // Goodbye!
16591            boolean removed;
16592            synchronized (mPidsSelfLocked) {
16593                mPidsSelfLocked.remove(app.pid);
16594                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16595            }
16596            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16597            if (app.isolated) {
16598                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16599            }
16600            app.setPid(0);
16601        }
16602        return false;
16603    }
16604
16605    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16606        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16607            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16608            if (cpr.launchingApp == app) {
16609                return true;
16610            }
16611        }
16612        return false;
16613    }
16614
16615    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16616        // Look through the content providers we are waiting to have launched,
16617        // and if any run in this process then either schedule a restart of
16618        // the process or kill the client waiting for it if this process has
16619        // gone bad.
16620        boolean restart = false;
16621        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16622            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16623            if (cpr.launchingApp == app) {
16624                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16625                    restart = true;
16626                } else {
16627                    removeDyingProviderLocked(app, cpr, true);
16628                }
16629            }
16630        }
16631        return restart;
16632    }
16633
16634    // =========================================================
16635    // SERVICES
16636    // =========================================================
16637
16638    @Override
16639    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16640            int flags) {
16641        enforceNotIsolatedCaller("getServices");
16642        synchronized (this) {
16643            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16644        }
16645    }
16646
16647    @Override
16648    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16649        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16650        synchronized (this) {
16651            return mServices.getRunningServiceControlPanelLocked(name);
16652        }
16653    }
16654
16655    @Override
16656    public ComponentName startService(IApplicationThread caller, Intent service,
16657            String resolvedType, String callingPackage, int userId)
16658            throws TransactionTooLargeException {
16659        enforceNotIsolatedCaller("startService");
16660        // Refuse possible leaked file descriptors
16661        if (service != null && service.hasFileDescriptors() == true) {
16662            throw new IllegalArgumentException("File descriptors passed in Intent");
16663        }
16664
16665        if (callingPackage == null) {
16666            throw new IllegalArgumentException("callingPackage cannot be null");
16667        }
16668
16669        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16670                "startService: " + service + " type=" + resolvedType);
16671        synchronized(this) {
16672            final int callingPid = Binder.getCallingPid();
16673            final int callingUid = Binder.getCallingUid();
16674            final long origId = Binder.clearCallingIdentity();
16675            ComponentName res = mServices.startServiceLocked(caller, service,
16676                    resolvedType, callingPid, callingUid, callingPackage, userId);
16677            Binder.restoreCallingIdentity(origId);
16678            return res;
16679        }
16680    }
16681
16682    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16683            String callingPackage, int userId)
16684            throws TransactionTooLargeException {
16685        synchronized(this) {
16686            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16687                    "startServiceInPackage: " + service + " type=" + resolvedType);
16688            final long origId = Binder.clearCallingIdentity();
16689            ComponentName res = mServices.startServiceLocked(null, service,
16690                    resolvedType, -1, uid, callingPackage, userId);
16691            Binder.restoreCallingIdentity(origId);
16692            return res;
16693        }
16694    }
16695
16696    @Override
16697    public int stopService(IApplicationThread caller, Intent service,
16698            String resolvedType, int userId) {
16699        enforceNotIsolatedCaller("stopService");
16700        // Refuse possible leaked file descriptors
16701        if (service != null && service.hasFileDescriptors() == true) {
16702            throw new IllegalArgumentException("File descriptors passed in Intent");
16703        }
16704
16705        synchronized(this) {
16706            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16707        }
16708    }
16709
16710    @Override
16711    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16712        enforceNotIsolatedCaller("peekService");
16713        // Refuse possible leaked file descriptors
16714        if (service != null && service.hasFileDescriptors() == true) {
16715            throw new IllegalArgumentException("File descriptors passed in Intent");
16716        }
16717
16718        if (callingPackage == null) {
16719            throw new IllegalArgumentException("callingPackage cannot be null");
16720        }
16721
16722        synchronized(this) {
16723            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16724        }
16725    }
16726
16727    @Override
16728    public boolean stopServiceToken(ComponentName className, IBinder token,
16729            int startId) {
16730        synchronized(this) {
16731            return mServices.stopServiceTokenLocked(className, token, startId);
16732        }
16733    }
16734
16735    @Override
16736    public void setServiceForeground(ComponentName className, IBinder token,
16737            int id, Notification notification, int flags) {
16738        synchronized(this) {
16739            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
16740        }
16741    }
16742
16743    @Override
16744    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16745            boolean requireFull, String name, String callerPackage) {
16746        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16747                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16748    }
16749
16750    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16751            String className, int flags) {
16752        boolean result = false;
16753        // For apps that don't have pre-defined UIDs, check for permission
16754        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16755            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16756                if (ActivityManager.checkUidPermission(
16757                        INTERACT_ACROSS_USERS,
16758                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16759                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16760                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16761                            + " requests FLAG_SINGLE_USER, but app does not hold "
16762                            + INTERACT_ACROSS_USERS;
16763                    Slog.w(TAG, msg);
16764                    throw new SecurityException(msg);
16765                }
16766                // Permission passed
16767                result = true;
16768            }
16769        } else if ("system".equals(componentProcessName)) {
16770            result = true;
16771        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16772            // Phone app and persistent apps are allowed to export singleuser providers.
16773            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16774                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16775        }
16776        if (DEBUG_MU) Slog.v(TAG_MU,
16777                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16778                + Integer.toHexString(flags) + ") = " + result);
16779        return result;
16780    }
16781
16782    /**
16783     * Checks to see if the caller is in the same app as the singleton
16784     * component, or the component is in a special app. It allows special apps
16785     * to export singleton components but prevents exporting singleton
16786     * components for regular apps.
16787     */
16788    boolean isValidSingletonCall(int callingUid, int componentUid) {
16789        int componentAppId = UserHandle.getAppId(componentUid);
16790        return UserHandle.isSameApp(callingUid, componentUid)
16791                || componentAppId == Process.SYSTEM_UID
16792                || componentAppId == Process.PHONE_UID
16793                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16794                        == PackageManager.PERMISSION_GRANTED;
16795    }
16796
16797    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16798            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16799            int userId) throws TransactionTooLargeException {
16800        enforceNotIsolatedCaller("bindService");
16801
16802        // Refuse possible leaked file descriptors
16803        if (service != null && service.hasFileDescriptors() == true) {
16804            throw new IllegalArgumentException("File descriptors passed in Intent");
16805        }
16806
16807        if (callingPackage == null) {
16808            throw new IllegalArgumentException("callingPackage cannot be null");
16809        }
16810
16811        synchronized(this) {
16812            return mServices.bindServiceLocked(caller, token, service,
16813                    resolvedType, connection, flags, callingPackage, userId);
16814        }
16815    }
16816
16817    public boolean unbindService(IServiceConnection connection) {
16818        synchronized (this) {
16819            return mServices.unbindServiceLocked(connection);
16820        }
16821    }
16822
16823    public void publishService(IBinder token, Intent intent, IBinder service) {
16824        // Refuse possible leaked file descriptors
16825        if (intent != null && intent.hasFileDescriptors() == true) {
16826            throw new IllegalArgumentException("File descriptors passed in Intent");
16827        }
16828
16829        synchronized(this) {
16830            if (!(token instanceof ServiceRecord)) {
16831                throw new IllegalArgumentException("Invalid service token");
16832            }
16833            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16834        }
16835    }
16836
16837    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16838        // Refuse possible leaked file descriptors
16839        if (intent != null && intent.hasFileDescriptors() == true) {
16840            throw new IllegalArgumentException("File descriptors passed in Intent");
16841        }
16842
16843        synchronized(this) {
16844            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16845        }
16846    }
16847
16848    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16849        synchronized(this) {
16850            if (!(token instanceof ServiceRecord)) {
16851                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16852                throw new IllegalArgumentException("Invalid service token");
16853            }
16854            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16855        }
16856    }
16857
16858    // =========================================================
16859    // BACKUP AND RESTORE
16860    // =========================================================
16861
16862    // Cause the target app to be launched if necessary and its backup agent
16863    // instantiated.  The backup agent will invoke backupAgentCreated() on the
16864    // activity manager to announce its creation.
16865    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16866        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16867                "bindBackupAgent: app=" + app + " mode=" + backupMode);
16868        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16869
16870        synchronized(this) {
16871            // !!! TODO: currently no check here that we're already bound
16872            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16873            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16874            synchronized (stats) {
16875                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16876            }
16877
16878            // Backup agent is now in use, its package can't be stopped.
16879            try {
16880                AppGlobals.getPackageManager().setPackageStoppedState(
16881                        app.packageName, false, UserHandle.getUserId(app.uid));
16882            } catch (RemoteException e) {
16883            } catch (IllegalArgumentException e) {
16884                Slog.w(TAG, "Failed trying to unstop package "
16885                        + app.packageName + ": " + e);
16886            }
16887
16888            BackupRecord r = new BackupRecord(ss, app, backupMode);
16889            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16890                    ? new ComponentName(app.packageName, app.backupAgentName)
16891                    : new ComponentName("android", "FullBackupAgent");
16892            // startProcessLocked() returns existing proc's record if it's already running
16893            ProcessRecord proc = startProcessLocked(app.processName, app,
16894                    false, 0, "backup", hostingName, false, false, false);
16895            if (proc == null) {
16896                Slog.e(TAG, "Unable to start backup agent process " + r);
16897                return false;
16898            }
16899
16900            // If the app is a regular app (uid >= 10000) and not the system server or phone
16901            // process, etc, then mark it as being in full backup so that certain calls to the
16902            // process can be blocked. This is not reset to false anywhere because we kill the
16903            // process after the full backup is done and the ProcessRecord will vaporize anyway.
16904            if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
16905                proc.inFullBackup = true;
16906            }
16907            r.app = proc;
16908            mBackupTarget = r;
16909            mBackupAppName = app.packageName;
16910
16911            // Try not to kill the process during backup
16912            updateOomAdjLocked(proc);
16913
16914            // If the process is already attached, schedule the creation of the backup agent now.
16915            // If it is not yet live, this will be done when it attaches to the framework.
16916            if (proc.thread != null) {
16917                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16918                try {
16919                    proc.thread.scheduleCreateBackupAgent(app,
16920                            compatibilityInfoForPackageLocked(app), backupMode);
16921                } catch (RemoteException e) {
16922                    // Will time out on the backup manager side
16923                }
16924            } else {
16925                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16926            }
16927            // Invariants: at this point, the target app process exists and the application
16928            // is either already running or in the process of coming up.  mBackupTarget and
16929            // mBackupAppName describe the app, so that when it binds back to the AM we
16930            // know that it's scheduled for a backup-agent operation.
16931        }
16932
16933        return true;
16934    }
16935
16936    @Override
16937    public void clearPendingBackup() {
16938        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16939        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16940
16941        synchronized (this) {
16942            mBackupTarget = null;
16943            mBackupAppName = null;
16944        }
16945    }
16946
16947    // A backup agent has just come up
16948    public void backupAgentCreated(String agentPackageName, IBinder agent) {
16949        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16950                + " = " + agent);
16951
16952        synchronized(this) {
16953            if (!agentPackageName.equals(mBackupAppName)) {
16954                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16955                return;
16956            }
16957        }
16958
16959        long oldIdent = Binder.clearCallingIdentity();
16960        try {
16961            IBackupManager bm = IBackupManager.Stub.asInterface(
16962                    ServiceManager.getService(Context.BACKUP_SERVICE));
16963            bm.agentConnected(agentPackageName, agent);
16964        } catch (RemoteException e) {
16965            // can't happen; the backup manager service is local
16966        } catch (Exception e) {
16967            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16968            e.printStackTrace();
16969        } finally {
16970            Binder.restoreCallingIdentity(oldIdent);
16971        }
16972    }
16973
16974    // done with this agent
16975    public void unbindBackupAgent(ApplicationInfo appInfo) {
16976        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16977        if (appInfo == null) {
16978            Slog.w(TAG, "unbind backup agent for null app");
16979            return;
16980        }
16981
16982        synchronized(this) {
16983            try {
16984                if (mBackupAppName == null) {
16985                    Slog.w(TAG, "Unbinding backup agent with no active backup");
16986                    return;
16987                }
16988
16989                if (!mBackupAppName.equals(appInfo.packageName)) {
16990                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16991                    return;
16992                }
16993
16994                // Not backing this app up any more; reset its OOM adjustment
16995                final ProcessRecord proc = mBackupTarget.app;
16996                updateOomAdjLocked(proc);
16997
16998                // If the app crashed during backup, 'thread' will be null here
16999                if (proc.thread != null) {
17000                    try {
17001                        proc.thread.scheduleDestroyBackupAgent(appInfo,
17002                                compatibilityInfoForPackageLocked(appInfo));
17003                    } catch (Exception e) {
17004                        Slog.e(TAG, "Exception when unbinding backup agent:");
17005                        e.printStackTrace();
17006                    }
17007                }
17008            } finally {
17009                mBackupTarget = null;
17010                mBackupAppName = null;
17011            }
17012        }
17013    }
17014    // =========================================================
17015    // BROADCASTS
17016    // =========================================================
17017
17018    boolean isPendingBroadcastProcessLocked(int pid) {
17019        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17020                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17021    }
17022
17023    void skipPendingBroadcastLocked(int pid) {
17024            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17025            for (BroadcastQueue queue : mBroadcastQueues) {
17026                queue.skipPendingBroadcastLocked(pid);
17027            }
17028    }
17029
17030    // The app just attached; send any pending broadcasts that it should receive
17031    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17032        boolean didSomething = false;
17033        for (BroadcastQueue queue : mBroadcastQueues) {
17034            didSomething |= queue.sendPendingBroadcastsLocked(app);
17035        }
17036        return didSomething;
17037    }
17038
17039    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17040            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17041        enforceNotIsolatedCaller("registerReceiver");
17042        ArrayList<Intent> stickyIntents = null;
17043        ProcessRecord callerApp = null;
17044        int callingUid;
17045        int callingPid;
17046        synchronized(this) {
17047            if (caller != null) {
17048                callerApp = getRecordForAppLocked(caller);
17049                if (callerApp == null) {
17050                    throw new SecurityException(
17051                            "Unable to find app for caller " + caller
17052                            + " (pid=" + Binder.getCallingPid()
17053                            + ") when registering receiver " + receiver);
17054                }
17055                if (callerApp.info.uid != Process.SYSTEM_UID &&
17056                        !callerApp.pkgList.containsKey(callerPackage) &&
17057                        !"android".equals(callerPackage)) {
17058                    throw new SecurityException("Given caller package " + callerPackage
17059                            + " is not running in process " + callerApp);
17060                }
17061                callingUid = callerApp.info.uid;
17062                callingPid = callerApp.pid;
17063            } else {
17064                callerPackage = null;
17065                callingUid = Binder.getCallingUid();
17066                callingPid = Binder.getCallingPid();
17067            }
17068
17069            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17070                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17071
17072            Iterator<String> actions = filter.actionsIterator();
17073            if (actions == null) {
17074                ArrayList<String> noAction = new ArrayList<String>(1);
17075                noAction.add(null);
17076                actions = noAction.iterator();
17077            }
17078
17079            // Collect stickies of users
17080            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17081            while (actions.hasNext()) {
17082                String action = actions.next();
17083                for (int id : userIds) {
17084                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17085                    if (stickies != null) {
17086                        ArrayList<Intent> intents = stickies.get(action);
17087                        if (intents != null) {
17088                            if (stickyIntents == null) {
17089                                stickyIntents = new ArrayList<Intent>();
17090                            }
17091                            stickyIntents.addAll(intents);
17092                        }
17093                    }
17094                }
17095            }
17096        }
17097
17098        ArrayList<Intent> allSticky = null;
17099        if (stickyIntents != null) {
17100            final ContentResolver resolver = mContext.getContentResolver();
17101            // Look for any matching sticky broadcasts...
17102            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17103                Intent intent = stickyIntents.get(i);
17104                // If intent has scheme "content", it will need to acccess
17105                // provider that needs to lock mProviderMap in ActivityThread
17106                // and also it may need to wait application response, so we
17107                // cannot lock ActivityManagerService here.
17108                if (filter.match(resolver, intent, true, TAG) >= 0) {
17109                    if (allSticky == null) {
17110                        allSticky = new ArrayList<Intent>();
17111                    }
17112                    allSticky.add(intent);
17113                }
17114            }
17115        }
17116
17117        // The first sticky in the list is returned directly back to the client.
17118        Intent sticky = allSticky != null ? allSticky.get(0) : null;
17119        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17120        if (receiver == null) {
17121            return sticky;
17122        }
17123
17124        synchronized (this) {
17125            if (callerApp != null && (callerApp.thread == null
17126                    || callerApp.thread.asBinder() != caller.asBinder())) {
17127                // Original caller already died
17128                return null;
17129            }
17130            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17131            if (rl == null) {
17132                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17133                        userId, receiver);
17134                if (rl.app != null) {
17135                    rl.app.receivers.add(rl);
17136                } else {
17137                    try {
17138                        receiver.asBinder().linkToDeath(rl, 0);
17139                    } catch (RemoteException e) {
17140                        return sticky;
17141                    }
17142                    rl.linkedToDeath = true;
17143                }
17144                mRegisteredReceivers.put(receiver.asBinder(), rl);
17145            } else if (rl.uid != callingUid) {
17146                throw new IllegalArgumentException(
17147                        "Receiver requested to register for uid " + callingUid
17148                        + " was previously registered for uid " + rl.uid);
17149            } else if (rl.pid != callingPid) {
17150                throw new IllegalArgumentException(
17151                        "Receiver requested to register for pid " + callingPid
17152                        + " was previously registered for pid " + rl.pid);
17153            } else if (rl.userId != userId) {
17154                throw new IllegalArgumentException(
17155                        "Receiver requested to register for user " + userId
17156                        + " was previously registered for user " + rl.userId);
17157            }
17158            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17159                    permission, callingUid, userId);
17160            rl.add(bf);
17161            if (!bf.debugCheck()) {
17162                Slog.w(TAG, "==> For Dynamic broadcast");
17163            }
17164            mReceiverResolver.addFilter(bf);
17165
17166            // Enqueue broadcasts for all existing stickies that match
17167            // this filter.
17168            if (allSticky != null) {
17169                ArrayList receivers = new ArrayList();
17170                receivers.add(bf);
17171
17172                final int stickyCount = allSticky.size();
17173                for (int i = 0; i < stickyCount; i++) {
17174                    Intent intent = allSticky.get(i);
17175                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17176                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17177                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17178                            null, 0, null, null, false, true, true, -1);
17179                    queue.enqueueParallelBroadcastLocked(r);
17180                    queue.scheduleBroadcastsLocked();
17181                }
17182            }
17183
17184            return sticky;
17185        }
17186    }
17187
17188    public void unregisterReceiver(IIntentReceiver receiver) {
17189        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17190
17191        final long origId = Binder.clearCallingIdentity();
17192        try {
17193            boolean doTrim = false;
17194
17195            synchronized(this) {
17196                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17197                if (rl != null) {
17198                    final BroadcastRecord r = rl.curBroadcast;
17199                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17200                        final boolean doNext = r.queue.finishReceiverLocked(
17201                                r, r.resultCode, r.resultData, r.resultExtras,
17202                                r.resultAbort, false);
17203                        if (doNext) {
17204                            doTrim = true;
17205                            r.queue.processNextBroadcast(false);
17206                        }
17207                    }
17208
17209                    if (rl.app != null) {
17210                        rl.app.receivers.remove(rl);
17211                    }
17212                    removeReceiverLocked(rl);
17213                    if (rl.linkedToDeath) {
17214                        rl.linkedToDeath = false;
17215                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17216                    }
17217                }
17218            }
17219
17220            // If we actually concluded any broadcasts, we might now be able
17221            // to trim the recipients' apps from our working set
17222            if (doTrim) {
17223                trimApplications();
17224                return;
17225            }
17226
17227        } finally {
17228            Binder.restoreCallingIdentity(origId);
17229        }
17230    }
17231
17232    void removeReceiverLocked(ReceiverList rl) {
17233        mRegisteredReceivers.remove(rl.receiver.asBinder());
17234        for (int i = rl.size() - 1; i >= 0; i--) {
17235            mReceiverResolver.removeFilter(rl.get(i));
17236        }
17237    }
17238
17239    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17240        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17241            ProcessRecord r = mLruProcesses.get(i);
17242            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17243                try {
17244                    r.thread.dispatchPackageBroadcast(cmd, packages);
17245                } catch (RemoteException ex) {
17246                }
17247            }
17248        }
17249    }
17250
17251    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17252            int callingUid, int[] users) {
17253        // TODO: come back and remove this assumption to triage all broadcasts
17254        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17255
17256        List<ResolveInfo> receivers = null;
17257        try {
17258            HashSet<ComponentName> singleUserReceivers = null;
17259            boolean scannedFirstReceivers = false;
17260            for (int user : users) {
17261                // Skip users that have Shell restrictions, with exception of always permitted
17262                // Shell broadcasts
17263                if (callingUid == Process.SHELL_UID
17264                        && mUserController.hasUserRestriction(
17265                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17266                        && !isPermittedShellBroadcast(intent)) {
17267                    continue;
17268                }
17269                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17270                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17271                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17272                    // If this is not the system user, we need to check for
17273                    // any receivers that should be filtered out.
17274                    for (int i=0; i<newReceivers.size(); i++) {
17275                        ResolveInfo ri = newReceivers.get(i);
17276                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17277                            newReceivers.remove(i);
17278                            i--;
17279                        }
17280                    }
17281                }
17282                if (newReceivers != null && newReceivers.size() == 0) {
17283                    newReceivers = null;
17284                }
17285                if (receivers == null) {
17286                    receivers = newReceivers;
17287                } else if (newReceivers != null) {
17288                    // We need to concatenate the additional receivers
17289                    // found with what we have do far.  This would be easy,
17290                    // but we also need to de-dup any receivers that are
17291                    // singleUser.
17292                    if (!scannedFirstReceivers) {
17293                        // Collect any single user receivers we had already retrieved.
17294                        scannedFirstReceivers = true;
17295                        for (int i=0; i<receivers.size(); i++) {
17296                            ResolveInfo ri = receivers.get(i);
17297                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17298                                ComponentName cn = new ComponentName(
17299                                        ri.activityInfo.packageName, ri.activityInfo.name);
17300                                if (singleUserReceivers == null) {
17301                                    singleUserReceivers = new HashSet<ComponentName>();
17302                                }
17303                                singleUserReceivers.add(cn);
17304                            }
17305                        }
17306                    }
17307                    // Add the new results to the existing results, tracking
17308                    // and de-dupping single user receivers.
17309                    for (int i=0; i<newReceivers.size(); i++) {
17310                        ResolveInfo ri = newReceivers.get(i);
17311                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17312                            ComponentName cn = new ComponentName(
17313                                    ri.activityInfo.packageName, ri.activityInfo.name);
17314                            if (singleUserReceivers == null) {
17315                                singleUserReceivers = new HashSet<ComponentName>();
17316                            }
17317                            if (!singleUserReceivers.contains(cn)) {
17318                                singleUserReceivers.add(cn);
17319                                receivers.add(ri);
17320                            }
17321                        } else {
17322                            receivers.add(ri);
17323                        }
17324                    }
17325                }
17326            }
17327        } catch (RemoteException ex) {
17328            // pm is in same process, this will never happen.
17329        }
17330        return receivers;
17331    }
17332
17333    private boolean isPermittedShellBroadcast(Intent intent) {
17334        // remote bugreport should always be allowed to be taken
17335        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17336    }
17337
17338    final int broadcastIntentLocked(ProcessRecord callerApp,
17339            String callerPackage, Intent intent, String resolvedType,
17340            IIntentReceiver resultTo, int resultCode, String resultData,
17341            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17342            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17343        intent = new Intent(intent);
17344
17345        // By default broadcasts do not go to stopped apps.
17346        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17347
17348        // If we have not finished booting, don't allow this to launch new processes.
17349        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17350            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17351        }
17352
17353        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17354                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17355                + " ordered=" + ordered + " userid=" + userId);
17356        if ((resultTo != null) && !ordered) {
17357            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17358        }
17359
17360        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17361                ALLOW_NON_FULL, "broadcast", callerPackage);
17362
17363        // Make sure that the user who is receiving this broadcast is running.
17364        // If not, we will just skip it. Make an exception for shutdown broadcasts
17365        // and upgrade steps.
17366
17367        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17368            if ((callingUid != Process.SYSTEM_UID
17369                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17370                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17371                Slog.w(TAG, "Skipping broadcast of " + intent
17372                        + ": user " + userId + " is stopped");
17373                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17374            }
17375        }
17376
17377        BroadcastOptions brOptions = null;
17378        if (bOptions != null) {
17379            brOptions = new BroadcastOptions(bOptions);
17380            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17381                // See if the caller is allowed to do this.  Note we are checking against
17382                // the actual real caller (not whoever provided the operation as say a
17383                // PendingIntent), because that who is actually supplied the arguments.
17384                if (checkComponentPermission(
17385                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17386                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17387                        != PackageManager.PERMISSION_GRANTED) {
17388                    String msg = "Permission Denial: " + intent.getAction()
17389                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17390                            + ", uid=" + callingUid + ")"
17391                            + " requires "
17392                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17393                    Slog.w(TAG, msg);
17394                    throw new SecurityException(msg);
17395                }
17396            }
17397        }
17398
17399        // Verify that protected broadcasts are only being sent by system code,
17400        // and that system code is only sending protected broadcasts.
17401        final String action = intent.getAction();
17402        final boolean isProtectedBroadcast;
17403        try {
17404            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17405        } catch (RemoteException e) {
17406            Slog.w(TAG, "Remote exception", e);
17407            return ActivityManager.BROADCAST_SUCCESS;
17408        }
17409
17410        final boolean isCallerSystem;
17411        switch (UserHandle.getAppId(callingUid)) {
17412            case Process.ROOT_UID:
17413            case Process.SYSTEM_UID:
17414            case Process.PHONE_UID:
17415            case Process.BLUETOOTH_UID:
17416            case Process.NFC_UID:
17417                isCallerSystem = true;
17418                break;
17419            default:
17420                isCallerSystem = (callerApp != null) && callerApp.persistent;
17421                break;
17422        }
17423
17424        if (isCallerSystem) {
17425            if (isProtectedBroadcast
17426                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17427                    || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17428                    || Intent.ACTION_MEDIA_BUTTON.equals(action)
17429                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17430                    || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17431                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17432                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17433                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17434                    || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17435                    || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17436                // Broadcast is either protected, or it's a public action that
17437                // we've relaxed, so it's fine for system internals to send.
17438            } else {
17439                // The vast majority of broadcasts sent from system internals
17440                // should be protected to avoid security holes, so yell loudly
17441                // to ensure we examine these cases.
17442                if (callerApp != null) {
17443                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17444                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17445                            new Throwable());
17446                } else {
17447                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17448                            + " from system uid " + UserHandle.formatUid(callingUid)
17449                            + " pkg " + callerPackage,
17450                            new Throwable());
17451                }
17452            }
17453
17454        } else {
17455            if (isProtectedBroadcast) {
17456                String msg = "Permission Denial: not allowed to send broadcast "
17457                        + action + " from pid="
17458                        + callingPid + ", uid=" + callingUid;
17459                Slog.w(TAG, msg);
17460                throw new SecurityException(msg);
17461
17462            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17463                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17464                // Special case for compatibility: we don't want apps to send this,
17465                // but historically it has not been protected and apps may be using it
17466                // to poke their own app widget.  So, instead of making it protected,
17467                // just limit it to the caller.
17468                if (callerPackage == null) {
17469                    String msg = "Permission Denial: not allowed to send broadcast "
17470                            + action + " from unknown caller.";
17471                    Slog.w(TAG, msg);
17472                    throw new SecurityException(msg);
17473                } else if (intent.getComponent() != null) {
17474                    // They are good enough to send to an explicit component...  verify
17475                    // it is being sent to the calling app.
17476                    if (!intent.getComponent().getPackageName().equals(
17477                            callerPackage)) {
17478                        String msg = "Permission Denial: not allowed to send broadcast "
17479                                + action + " to "
17480                                + intent.getComponent().getPackageName() + " from "
17481                                + callerPackage;
17482                        Slog.w(TAG, msg);
17483                        throw new SecurityException(msg);
17484                    }
17485                } else {
17486                    // Limit broadcast to their own package.
17487                    intent.setPackage(callerPackage);
17488                }
17489            }
17490        }
17491
17492        if (action != null) {
17493            switch (action) {
17494                case Intent.ACTION_UID_REMOVED:
17495                case Intent.ACTION_PACKAGE_REMOVED:
17496                case Intent.ACTION_PACKAGE_CHANGED:
17497                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17498                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17499                case Intent.ACTION_PACKAGES_SUSPENDED:
17500                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17501                    // Handle special intents: if this broadcast is from the package
17502                    // manager about a package being removed, we need to remove all of
17503                    // its activities from the history stack.
17504                    if (checkComponentPermission(
17505                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17506                            callingPid, callingUid, -1, true)
17507                            != PackageManager.PERMISSION_GRANTED) {
17508                        String msg = "Permission Denial: " + intent.getAction()
17509                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17510                                + ", uid=" + callingUid + ")"
17511                                + " requires "
17512                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17513                        Slog.w(TAG, msg);
17514                        throw new SecurityException(msg);
17515                    }
17516                    switch (action) {
17517                        case Intent.ACTION_UID_REMOVED:
17518                            final Bundle intentExtras = intent.getExtras();
17519                            final int uid = intentExtras != null
17520                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17521                            if (uid >= 0) {
17522                                mBatteryStatsService.removeUid(uid);
17523                                mAppOpsService.uidRemoved(uid);
17524                            }
17525                            break;
17526                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17527                            // If resources are unavailable just force stop all those packages
17528                            // and flush the attribute cache as well.
17529                            String list[] =
17530                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17531                            if (list != null && list.length > 0) {
17532                                for (int i = 0; i < list.length; i++) {
17533                                    forceStopPackageLocked(list[i], -1, false, true, true,
17534                                            false, false, userId, "storage unmount");
17535                                }
17536                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17537                                sendPackageBroadcastLocked(
17538                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17539                                        userId);
17540                            }
17541                            break;
17542                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17543                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17544                            break;
17545                        case Intent.ACTION_PACKAGE_REMOVED:
17546                        case Intent.ACTION_PACKAGE_CHANGED:
17547                            Uri data = intent.getData();
17548                            String ssp;
17549                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17550                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17551                                final boolean replacing =
17552                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17553                                final boolean killProcess =
17554                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17555                                final boolean fullUninstall = removed && !replacing;
17556                                if (removed) {
17557                                    if (killProcess) {
17558                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
17559                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17560                                                false, true, true, false, fullUninstall, userId,
17561                                                removed ? "pkg removed" : "pkg changed");
17562                                    }
17563                                    final int cmd = killProcess
17564                                            ? IApplicationThread.PACKAGE_REMOVED
17565                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17566                                    sendPackageBroadcastLocked(cmd,
17567                                            new String[] {ssp}, userId);
17568                                    if (fullUninstall) {
17569                                        mAppOpsService.packageRemoved(
17570                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17571
17572                                        // Remove all permissions granted from/to this package
17573                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17574
17575                                        removeTasksByPackageNameLocked(ssp, userId);
17576                                        mBatteryStatsService.notePackageUninstalled(ssp);
17577                                    }
17578                                } else {
17579                                    if (killProcess) {
17580                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
17581                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17582                                                userId, ProcessList.INVALID_ADJ,
17583                                                false, true, true, false, "change " + ssp);
17584                                    }
17585                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17586                                            intent.getStringArrayExtra(
17587                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17588                                }
17589                            }
17590                            break;
17591                        case Intent.ACTION_PACKAGES_SUSPENDED:
17592                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17593                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17594                                    intent.getAction());
17595                            final String[] packageNames = intent.getStringArrayExtra(
17596                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17597                            final int userHandle = intent.getIntExtra(
17598                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17599
17600                            synchronized(ActivityManagerService.this) {
17601                                mRecentTasks.onPackagesSuspendedChanged(
17602                                        packageNames, suspended, userHandle);
17603                            }
17604                            break;
17605                    }
17606                    break;
17607                case Intent.ACTION_PACKAGE_REPLACED:
17608                {
17609                    final Uri data = intent.getData();
17610                    final String ssp;
17611                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17612                        final ApplicationInfo aInfo =
17613                                getPackageManagerInternalLocked().getApplicationInfo(
17614                                        ssp,
17615                                        userId);
17616                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17617                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17618                                new String[] {ssp}, userId);
17619                    }
17620                    break;
17621                }
17622                case Intent.ACTION_PACKAGE_ADDED:
17623                {
17624                    // Special case for adding a package: by default turn on compatibility mode.
17625                    Uri data = intent.getData();
17626                    String ssp;
17627                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17628                        final boolean replacing =
17629                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17630                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17631
17632                        try {
17633                            ApplicationInfo ai = AppGlobals.getPackageManager().
17634                                    getApplicationInfo(ssp, 0, 0);
17635                            mBatteryStatsService.notePackageInstalled(ssp,
17636                                    ai != null ? ai.versionCode : 0);
17637                        } catch (RemoteException e) {
17638                        }
17639                    }
17640                    break;
17641                }
17642                case Intent.ACTION_TIMEZONE_CHANGED:
17643                    // If this is the time zone changed action, queue up a message that will reset
17644                    // the timezone of all currently running processes. This message will get
17645                    // queued up before the broadcast happens.
17646                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17647                    break;
17648                case Intent.ACTION_TIME_CHANGED:
17649                    // If the user set the time, let all running processes know.
17650                    final int is24Hour =
17651                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17652                                    : 0;
17653                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17654                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17655                    synchronized (stats) {
17656                        stats.noteCurrentTimeChangedLocked();
17657                    }
17658                    break;
17659                case Intent.ACTION_CLEAR_DNS_CACHE:
17660                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17661                    break;
17662                case Proxy.PROXY_CHANGE_ACTION:
17663                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17664                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17665                    break;
17666                case android.hardware.Camera.ACTION_NEW_PICTURE:
17667                case android.hardware.Camera.ACTION_NEW_VIDEO:
17668                    // These broadcasts are no longer allowed by the system, since they can
17669                    // cause significant thrashing at a crictical point (using the camera).
17670                    // Apps should use JobScehduler to monitor for media provider changes.
17671                    Slog.w(TAG, action + " no longer allowed; dropping from "
17672                            + UserHandle.formatUid(callingUid));
17673                    // Lie; we don't want to crash the app.
17674                    return ActivityManager.BROADCAST_SUCCESS;
17675            }
17676        }
17677
17678        // Add to the sticky list if requested.
17679        if (sticky) {
17680            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17681                    callingPid, callingUid)
17682                    != PackageManager.PERMISSION_GRANTED) {
17683                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17684                        + callingPid + ", uid=" + callingUid
17685                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17686                Slog.w(TAG, msg);
17687                throw new SecurityException(msg);
17688            }
17689            if (requiredPermissions != null && requiredPermissions.length > 0) {
17690                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17691                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17692                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17693            }
17694            if (intent.getComponent() != null) {
17695                throw new SecurityException(
17696                        "Sticky broadcasts can't target a specific component");
17697            }
17698            // We use userId directly here, since the "all" target is maintained
17699            // as a separate set of sticky broadcasts.
17700            if (userId != UserHandle.USER_ALL) {
17701                // But first, if this is not a broadcast to all users, then
17702                // make sure it doesn't conflict with an existing broadcast to
17703                // all users.
17704                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17705                        UserHandle.USER_ALL);
17706                if (stickies != null) {
17707                    ArrayList<Intent> list = stickies.get(intent.getAction());
17708                    if (list != null) {
17709                        int N = list.size();
17710                        int i;
17711                        for (i=0; i<N; i++) {
17712                            if (intent.filterEquals(list.get(i))) {
17713                                throw new IllegalArgumentException(
17714                                        "Sticky broadcast " + intent + " for user "
17715                                        + userId + " conflicts with existing global broadcast");
17716                            }
17717                        }
17718                    }
17719                }
17720            }
17721            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17722            if (stickies == null) {
17723                stickies = new ArrayMap<>();
17724                mStickyBroadcasts.put(userId, stickies);
17725            }
17726            ArrayList<Intent> list = stickies.get(intent.getAction());
17727            if (list == null) {
17728                list = new ArrayList<>();
17729                stickies.put(intent.getAction(), list);
17730            }
17731            final int stickiesCount = list.size();
17732            int i;
17733            for (i = 0; i < stickiesCount; i++) {
17734                if (intent.filterEquals(list.get(i))) {
17735                    // This sticky already exists, replace it.
17736                    list.set(i, new Intent(intent));
17737                    break;
17738                }
17739            }
17740            if (i >= stickiesCount) {
17741                list.add(new Intent(intent));
17742            }
17743        }
17744
17745        int[] users;
17746        if (userId == UserHandle.USER_ALL) {
17747            // Caller wants broadcast to go to all started users.
17748            users = mUserController.getStartedUserArrayLocked();
17749        } else {
17750            // Caller wants broadcast to go to one specific user.
17751            users = new int[] {userId};
17752        }
17753
17754        // Figure out who all will receive this broadcast.
17755        List receivers = null;
17756        List<BroadcastFilter> registeredReceivers = null;
17757        // Need to resolve the intent to interested receivers...
17758        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17759                 == 0) {
17760            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17761        }
17762        if (intent.getComponent() == null) {
17763            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17764                // Query one target user at a time, excluding shell-restricted users
17765                for (int i = 0; i < users.length; i++) {
17766                    if (mUserController.hasUserRestriction(
17767                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17768                        continue;
17769                    }
17770                    List<BroadcastFilter> registeredReceiversForUser =
17771                            mReceiverResolver.queryIntent(intent,
17772                                    resolvedType, false, users[i]);
17773                    if (registeredReceivers == null) {
17774                        registeredReceivers = registeredReceiversForUser;
17775                    } else if (registeredReceiversForUser != null) {
17776                        registeredReceivers.addAll(registeredReceiversForUser);
17777                    }
17778                }
17779            } else {
17780                registeredReceivers = mReceiverResolver.queryIntent(intent,
17781                        resolvedType, false, userId);
17782            }
17783        }
17784
17785        final boolean replacePending =
17786                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17787
17788        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17789                + " replacePending=" + replacePending);
17790
17791        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17792        if (!ordered && NR > 0) {
17793            // If we are not serializing this broadcast, then send the
17794            // registered receivers separately so they don't wait for the
17795            // components to be launched.
17796            final BroadcastQueue queue = broadcastQueueForIntent(intent);
17797            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17798                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17799                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17800                    resultExtras, ordered, sticky, false, userId);
17801            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17802            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17803            if (!replaced) {
17804                queue.enqueueParallelBroadcastLocked(r);
17805                queue.scheduleBroadcastsLocked();
17806            }
17807            registeredReceivers = null;
17808            NR = 0;
17809        }
17810
17811        // Merge into one list.
17812        int ir = 0;
17813        if (receivers != null) {
17814            // A special case for PACKAGE_ADDED: do not allow the package
17815            // being added to see this broadcast.  This prevents them from
17816            // using this as a back door to get run as soon as they are
17817            // installed.  Maybe in the future we want to have a special install
17818            // broadcast or such for apps, but we'd like to deliberately make
17819            // this decision.
17820            String skipPackages[] = null;
17821            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17822                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17823                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17824                Uri data = intent.getData();
17825                if (data != null) {
17826                    String pkgName = data.getSchemeSpecificPart();
17827                    if (pkgName != null) {
17828                        skipPackages = new String[] { pkgName };
17829                    }
17830                }
17831            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17832                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17833            }
17834            if (skipPackages != null && (skipPackages.length > 0)) {
17835                for (String skipPackage : skipPackages) {
17836                    if (skipPackage != null) {
17837                        int NT = receivers.size();
17838                        for (int it=0; it<NT; it++) {
17839                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
17840                            if (curt.activityInfo.packageName.equals(skipPackage)) {
17841                                receivers.remove(it);
17842                                it--;
17843                                NT--;
17844                            }
17845                        }
17846                    }
17847                }
17848            }
17849
17850            int NT = receivers != null ? receivers.size() : 0;
17851            int it = 0;
17852            ResolveInfo curt = null;
17853            BroadcastFilter curr = null;
17854            while (it < NT && ir < NR) {
17855                if (curt == null) {
17856                    curt = (ResolveInfo)receivers.get(it);
17857                }
17858                if (curr == null) {
17859                    curr = registeredReceivers.get(ir);
17860                }
17861                if (curr.getPriority() >= curt.priority) {
17862                    // Insert this broadcast record into the final list.
17863                    receivers.add(it, curr);
17864                    ir++;
17865                    curr = null;
17866                    it++;
17867                    NT++;
17868                } else {
17869                    // Skip to the next ResolveInfo in the final list.
17870                    it++;
17871                    curt = null;
17872                }
17873            }
17874        }
17875        while (ir < NR) {
17876            if (receivers == null) {
17877                receivers = new ArrayList();
17878            }
17879            receivers.add(registeredReceivers.get(ir));
17880            ir++;
17881        }
17882
17883        if ((receivers != null && receivers.size() > 0)
17884                || resultTo != null) {
17885            BroadcastQueue queue = broadcastQueueForIntent(intent);
17886            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17887                    callerPackage, callingPid, callingUid, resolvedType,
17888                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17889                    resultData, resultExtras, ordered, sticky, false, userId);
17890
17891            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17892                    + ": prev had " + queue.mOrderedBroadcasts.size());
17893            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17894                    "Enqueueing broadcast " + r.intent.getAction());
17895
17896            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17897            if (!replaced) {
17898                queue.enqueueOrderedBroadcastLocked(r);
17899                queue.scheduleBroadcastsLocked();
17900            }
17901        }
17902
17903        return ActivityManager.BROADCAST_SUCCESS;
17904    }
17905
17906    final Intent verifyBroadcastLocked(Intent intent) {
17907        // Refuse possible leaked file descriptors
17908        if (intent != null && intent.hasFileDescriptors() == true) {
17909            throw new IllegalArgumentException("File descriptors passed in Intent");
17910        }
17911
17912        int flags = intent.getFlags();
17913
17914        if (!mProcessesReady) {
17915            // if the caller really truly claims to know what they're doing, go
17916            // ahead and allow the broadcast without launching any receivers
17917            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17918                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17919            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17920                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17921                        + " before boot completion");
17922                throw new IllegalStateException("Cannot broadcast before boot completed");
17923            }
17924        }
17925
17926        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17927            throw new IllegalArgumentException(
17928                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17929        }
17930
17931        return intent;
17932    }
17933
17934    public final int broadcastIntent(IApplicationThread caller,
17935            Intent intent, String resolvedType, IIntentReceiver resultTo,
17936            int resultCode, String resultData, Bundle resultExtras,
17937            String[] requiredPermissions, int appOp, Bundle bOptions,
17938            boolean serialized, boolean sticky, int userId) {
17939        enforceNotIsolatedCaller("broadcastIntent");
17940        synchronized(this) {
17941            intent = verifyBroadcastLocked(intent);
17942
17943            final ProcessRecord callerApp = getRecordForAppLocked(caller);
17944            final int callingPid = Binder.getCallingPid();
17945            final int callingUid = Binder.getCallingUid();
17946            final long origId = Binder.clearCallingIdentity();
17947            int res = broadcastIntentLocked(callerApp,
17948                    callerApp != null ? callerApp.info.packageName : null,
17949                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17950                    requiredPermissions, appOp, bOptions, serialized, sticky,
17951                    callingPid, callingUid, userId);
17952            Binder.restoreCallingIdentity(origId);
17953            return res;
17954        }
17955    }
17956
17957
17958    int broadcastIntentInPackage(String packageName, int uid,
17959            Intent intent, String resolvedType, IIntentReceiver resultTo,
17960            int resultCode, String resultData, Bundle resultExtras,
17961            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
17962            int userId) {
17963        synchronized(this) {
17964            intent = verifyBroadcastLocked(intent);
17965
17966            final long origId = Binder.clearCallingIdentity();
17967            String[] requiredPermissions = requiredPermission == null ? null
17968                    : new String[] {requiredPermission};
17969            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17970                    resultTo, resultCode, resultData, resultExtras,
17971                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
17972                    sticky, -1, uid, userId);
17973            Binder.restoreCallingIdentity(origId);
17974            return res;
17975        }
17976    }
17977
17978    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17979        // Refuse possible leaked file descriptors
17980        if (intent != null && intent.hasFileDescriptors() == true) {
17981            throw new IllegalArgumentException("File descriptors passed in Intent");
17982        }
17983
17984        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17985                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17986
17987        synchronized(this) {
17988            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17989                    != PackageManager.PERMISSION_GRANTED) {
17990                String msg = "Permission Denial: unbroadcastIntent() from pid="
17991                        + Binder.getCallingPid()
17992                        + ", uid=" + Binder.getCallingUid()
17993                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17994                Slog.w(TAG, msg);
17995                throw new SecurityException(msg);
17996            }
17997            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17998            if (stickies != null) {
17999                ArrayList<Intent> list = stickies.get(intent.getAction());
18000                if (list != null) {
18001                    int N = list.size();
18002                    int i;
18003                    for (i=0; i<N; i++) {
18004                        if (intent.filterEquals(list.get(i))) {
18005                            list.remove(i);
18006                            break;
18007                        }
18008                    }
18009                    if (list.size() <= 0) {
18010                        stickies.remove(intent.getAction());
18011                    }
18012                }
18013                if (stickies.size() <= 0) {
18014                    mStickyBroadcasts.remove(userId);
18015                }
18016            }
18017        }
18018    }
18019
18020    void backgroundServicesFinishedLocked(int userId) {
18021        for (BroadcastQueue queue : mBroadcastQueues) {
18022            queue.backgroundServicesFinishedLocked(userId);
18023        }
18024    }
18025
18026    public void finishReceiver(IBinder who, int resultCode, String resultData,
18027            Bundle resultExtras, boolean resultAbort, int flags) {
18028        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18029
18030        // Refuse possible leaked file descriptors
18031        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18032            throw new IllegalArgumentException("File descriptors passed in Bundle");
18033        }
18034
18035        final long origId = Binder.clearCallingIdentity();
18036        try {
18037            boolean doNext = false;
18038            BroadcastRecord r;
18039
18040            synchronized(this) {
18041                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18042                        ? mFgBroadcastQueue : mBgBroadcastQueue;
18043                r = queue.getMatchingOrderedReceiver(who);
18044                if (r != null) {
18045                    doNext = r.queue.finishReceiverLocked(r, resultCode,
18046                        resultData, resultExtras, resultAbort, true);
18047                }
18048            }
18049
18050            if (doNext) {
18051                r.queue.processNextBroadcast(false);
18052            }
18053            trimApplications();
18054        } finally {
18055            Binder.restoreCallingIdentity(origId);
18056        }
18057    }
18058
18059    // =========================================================
18060    // INSTRUMENTATION
18061    // =========================================================
18062
18063    public boolean startInstrumentation(ComponentName className,
18064            String profileFile, int flags, Bundle arguments,
18065            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18066            int userId, String abiOverride) {
18067        enforceNotIsolatedCaller("startInstrumentation");
18068        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18069                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18070        // Refuse possible leaked file descriptors
18071        if (arguments != null && arguments.hasFileDescriptors()) {
18072            throw new IllegalArgumentException("File descriptors passed in Bundle");
18073        }
18074
18075        synchronized(this) {
18076            InstrumentationInfo ii = null;
18077            ApplicationInfo ai = null;
18078            try {
18079                ii = mContext.getPackageManager().getInstrumentationInfo(
18080                    className, STOCK_PM_FLAGS);
18081                ai = AppGlobals.getPackageManager().getApplicationInfo(
18082                        ii.targetPackage, STOCK_PM_FLAGS, userId);
18083            } catch (PackageManager.NameNotFoundException e) {
18084            } catch (RemoteException e) {
18085            }
18086            if (ii == null) {
18087                reportStartInstrumentationFailureLocked(watcher, className,
18088                        "Unable to find instrumentation info for: " + className);
18089                return false;
18090            }
18091            if (ai == null) {
18092                reportStartInstrumentationFailureLocked(watcher, className,
18093                        "Unable to find instrumentation target package: " + ii.targetPackage);
18094                return false;
18095            }
18096            if (!ai.hasCode()) {
18097                reportStartInstrumentationFailureLocked(watcher, className,
18098                        "Instrumentation target has no code: " + ii.targetPackage);
18099                return false;
18100            }
18101
18102            int match = mContext.getPackageManager().checkSignatures(
18103                    ii.targetPackage, ii.packageName);
18104            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18105                String msg = "Permission Denial: starting instrumentation "
18106                        + className + " from pid="
18107                        + Binder.getCallingPid()
18108                        + ", uid=" + Binder.getCallingPid()
18109                        + " not allowed because package " + ii.packageName
18110                        + " does not have a signature matching the target "
18111                        + ii.targetPackage;
18112                reportStartInstrumentationFailureLocked(watcher, className, msg);
18113                throw new SecurityException(msg);
18114            }
18115
18116            final long origId = Binder.clearCallingIdentity();
18117            // Instrumentation can kill and relaunch even persistent processes
18118            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18119                    "start instr");
18120            ProcessRecord app = addAppLocked(ai, false, abiOverride);
18121            app.instrumentationClass = className;
18122            app.instrumentationInfo = ai;
18123            app.instrumentationProfileFile = profileFile;
18124            app.instrumentationArguments = arguments;
18125            app.instrumentationWatcher = watcher;
18126            app.instrumentationUiAutomationConnection = uiAutomationConnection;
18127            app.instrumentationResultClass = className;
18128            Binder.restoreCallingIdentity(origId);
18129        }
18130
18131        return true;
18132    }
18133
18134    /**
18135     * Report errors that occur while attempting to start Instrumentation.  Always writes the
18136     * error to the logs, but if somebody is watching, send the report there too.  This enables
18137     * the "am" command to report errors with more information.
18138     *
18139     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18140     * @param cn The component name of the instrumentation.
18141     * @param report The error report.
18142     */
18143    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18144            ComponentName cn, String report) {
18145        Slog.w(TAG, report);
18146        if (watcher != null) {
18147            Bundle results = new Bundle();
18148            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18149            results.putString("Error", report);
18150            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18151        }
18152    }
18153
18154    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18155        if (app.instrumentationWatcher != null) {
18156            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18157                    app.instrumentationClass, resultCode, results);
18158        }
18159
18160        // Can't call out of the system process with a lock held, so post a message.
18161        if (app.instrumentationUiAutomationConnection != null) {
18162            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18163                    app.instrumentationUiAutomationConnection).sendToTarget();
18164        }
18165
18166        app.instrumentationWatcher = null;
18167        app.instrumentationUiAutomationConnection = null;
18168        app.instrumentationClass = null;
18169        app.instrumentationInfo = null;
18170        app.instrumentationProfileFile = null;
18171        app.instrumentationArguments = null;
18172
18173        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18174                "finished inst");
18175    }
18176
18177    public void finishInstrumentation(IApplicationThread target,
18178            int resultCode, Bundle results) {
18179        int userId = UserHandle.getCallingUserId();
18180        // Refuse possible leaked file descriptors
18181        if (results != null && results.hasFileDescriptors()) {
18182            throw new IllegalArgumentException("File descriptors passed in Intent");
18183        }
18184
18185        synchronized(this) {
18186            ProcessRecord app = getRecordForAppLocked(target);
18187            if (app == null) {
18188                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18189                return;
18190            }
18191            final long origId = Binder.clearCallingIdentity();
18192            finishInstrumentationLocked(app, resultCode, results);
18193            Binder.restoreCallingIdentity(origId);
18194        }
18195    }
18196
18197    // =========================================================
18198    // CONFIGURATION
18199    // =========================================================
18200
18201    public ConfigurationInfo getDeviceConfigurationInfo() {
18202        ConfigurationInfo config = new ConfigurationInfo();
18203        synchronized (this) {
18204            config.reqTouchScreen = mConfiguration.touchscreen;
18205            config.reqKeyboardType = mConfiguration.keyboard;
18206            config.reqNavigation = mConfiguration.navigation;
18207            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18208                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18209                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18210            }
18211            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18212                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18213                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18214            }
18215            config.reqGlEsVersion = GL_ES_VERSION;
18216        }
18217        return config;
18218    }
18219
18220    ActivityStack getFocusedStack() {
18221        return mStackSupervisor.getFocusedStack();
18222    }
18223
18224    @Override
18225    public int getFocusedStackId() throws RemoteException {
18226        ActivityStack focusedStack = getFocusedStack();
18227        if (focusedStack != null) {
18228            return focusedStack.getStackId();
18229        }
18230        return -1;
18231    }
18232
18233    public Configuration getConfiguration() {
18234        Configuration ci;
18235        synchronized(this) {
18236            ci = new Configuration(mConfiguration);
18237            ci.userSetLocale = false;
18238        }
18239        return ci;
18240    }
18241
18242    @Override
18243    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18244        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18245        synchronized (this) {
18246            mSuppressResizeConfigChanges = suppress;
18247        }
18248    }
18249
18250    @Override
18251    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18252        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18253        if (fromStackId == HOME_STACK_ID) {
18254            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18255        }
18256        synchronized (this) {
18257            final long origId = Binder.clearCallingIdentity();
18258            try {
18259                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18260            } finally {
18261                Binder.restoreCallingIdentity(origId);
18262            }
18263        }
18264    }
18265
18266    @Override
18267    public void updatePersistentConfiguration(Configuration values) {
18268        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18269                "updateConfiguration()");
18270        enforceWriteSettingsPermission("updateConfiguration()");
18271        if (values == null) {
18272            throw new NullPointerException("Configuration must not be null");
18273        }
18274
18275        int userId = UserHandle.getCallingUserId();
18276
18277        synchronized(this) {
18278            final long origId = Binder.clearCallingIdentity();
18279            updateConfigurationLocked(values, null, false, true, userId);
18280            Binder.restoreCallingIdentity(origId);
18281        }
18282    }
18283
18284    private void updateFontScaleIfNeeded() {
18285        final int currentUserId;
18286        synchronized(this) {
18287            currentUserId = mUserController.getCurrentUserIdLocked();
18288        }
18289        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18290                FONT_SCALE, 1.0f, currentUserId);
18291        if (mConfiguration.fontScale != scaleFactor) {
18292            final Configuration configuration = mWindowManager.computeNewConfiguration();
18293            configuration.fontScale = scaleFactor;
18294            updatePersistentConfiguration(configuration);
18295        }
18296    }
18297
18298    private void enforceWriteSettingsPermission(String func) {
18299        int uid = Binder.getCallingUid();
18300        if (uid == Process.ROOT_UID) {
18301            return;
18302        }
18303
18304        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18305                Settings.getPackageNameForUid(mContext, uid), false)) {
18306            return;
18307        }
18308
18309        String msg = "Permission Denial: " + func + " from pid="
18310                + Binder.getCallingPid()
18311                + ", uid=" + uid
18312                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18313        Slog.w(TAG, msg);
18314        throw new SecurityException(msg);
18315    }
18316
18317    public void updateConfiguration(Configuration values) {
18318        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18319                "updateConfiguration()");
18320
18321        synchronized(this) {
18322            if (values == null && mWindowManager != null) {
18323                // sentinel: fetch the current configuration from the window manager
18324                values = mWindowManager.computeNewConfiguration();
18325            }
18326
18327            if (mWindowManager != null) {
18328                mProcessList.applyDisplaySize(mWindowManager);
18329            }
18330
18331            final long origId = Binder.clearCallingIdentity();
18332            if (values != null) {
18333                Settings.System.clearConfiguration(values);
18334            }
18335            updateConfigurationLocked(values, null, false);
18336            Binder.restoreCallingIdentity(origId);
18337        }
18338    }
18339
18340    void updateUserConfigurationLocked() {
18341        Configuration configuration = new Configuration(mConfiguration);
18342        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18343                mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
18344        updateConfigurationLocked(configuration, null, false);
18345    }
18346
18347    boolean updateConfigurationLocked(Configuration values,
18348            ActivityRecord starting, boolean initLocale) {
18349        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18350        return updateConfigurationLocked(values, starting, initLocale, false,
18351                UserHandle.USER_NULL);
18352    }
18353
18354    // To cache the list of supported system locales
18355    private String[] mSupportedSystemLocales = null;
18356
18357    /**
18358     * Do either or both things: (1) change the current configuration, and (2)
18359     * make sure the given activity is running with the (now) current
18360     * configuration.  Returns true if the activity has been left running, or
18361     * false if <var>starting</var> is being destroyed to match the new
18362     * configuration.
18363     *
18364     * @param userId is only used when persistent parameter is set to true to persist configuration
18365     *               for that particular user
18366     */
18367    private boolean updateConfigurationLocked(Configuration values,
18368            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18369        int changes = 0;
18370
18371        if (mWindowManager != null) {
18372            mWindowManager.deferSurfaceLayout();
18373        }
18374        if (values != null) {
18375            Configuration newConfig = new Configuration(mConfiguration);
18376            changes = newConfig.updateFrom(values);
18377            if (changes != 0) {
18378                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18379                        "Updating configuration to: " + values);
18380
18381                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18382
18383                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18384                    final LocaleList locales = values.getLocales();
18385                    int bestLocaleIndex = 0;
18386                    if (locales.size() > 1) {
18387                        if (mSupportedSystemLocales == null) {
18388                            mSupportedSystemLocales =
18389                                    Resources.getSystem().getAssets().getLocales();
18390                        }
18391                        bestLocaleIndex = Math.max(0,
18392                                locales.getFirstMatchIndex(mSupportedSystemLocales));
18393                    }
18394                    SystemProperties.set("persist.sys.locale",
18395                            locales.get(bestLocaleIndex).toLanguageTag());
18396                    LocaleList.setDefault(locales, bestLocaleIndex);
18397                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18398                            locales.get(bestLocaleIndex)));
18399                }
18400
18401                mConfigurationSeq++;
18402                if (mConfigurationSeq <= 0) {
18403                    mConfigurationSeq = 1;
18404                }
18405                newConfig.seq = mConfigurationSeq;
18406                mConfiguration = newConfig;
18407                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18408                mUsageStatsService.reportConfigurationChange(newConfig,
18409                        mUserController.getCurrentUserIdLocked());
18410                //mUsageStatsService.noteStartConfig(newConfig);
18411
18412                final Configuration configCopy = new Configuration(mConfiguration);
18413
18414                // TODO: If our config changes, should we auto dismiss any currently
18415                // showing dialogs?
18416                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18417
18418                AttributeCache ac = AttributeCache.instance();
18419                if (ac != null) {
18420                    ac.updateConfiguration(configCopy);
18421                }
18422
18423                // Make sure all resources in our process are updated
18424                // right now, so that anyone who is going to retrieve
18425                // resource values after we return will be sure to get
18426                // the new ones.  This is especially important during
18427                // boot, where the first config change needs to guarantee
18428                // all resources have that config before following boot
18429                // code is executed.
18430                mSystemThread.applyConfigurationToResources(configCopy);
18431
18432                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18433                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18434                    msg.obj = new Configuration(configCopy);
18435                    msg.arg1 = userId;
18436                    mHandler.sendMessage(msg);
18437                }
18438
18439                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18440                if (isDensityChange) {
18441                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18442                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18443                }
18444
18445                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18446                    ProcessRecord app = mLruProcesses.get(i);
18447                    try {
18448                        if (app.thread != null) {
18449                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18450                                    + app.processName + " new config " + mConfiguration);
18451                            app.thread.scheduleConfigurationChanged(configCopy);
18452                        }
18453                    } catch (Exception e) {
18454                    }
18455                }
18456                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18457                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18458                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18459                        | Intent.FLAG_RECEIVER_FOREGROUND);
18460                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18461                        null, AppOpsManager.OP_NONE, null, false, false,
18462                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18463                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18464                    // Tell the shortcut manager that the system locale changed.  It needs to know
18465                    // it before any other apps receive ACTION_LOCALE_CHANGED, which is why
18466                    // we "push" from here, rather than having the service listen to the broadcast.
18467                    final ShortcutServiceInternal shortcutService =
18468                            LocalServices.getService(ShortcutServiceInternal.class);
18469                    if (shortcutService != null) {
18470                        shortcutService.onSystemLocaleChangedNoLock();
18471                    }
18472
18473                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18474                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18475                    if (!mProcessesReady) {
18476                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18477                    }
18478                    broadcastIntentLocked(null, null, intent,
18479                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18480                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18481                }
18482            }
18483            // Update the configuration with WM first and check if any of the stacks need to be
18484            // resized due to the configuration change. If so, resize the stacks now and do any
18485            // relaunches if necessary. This way we don't need to relaunch again below in
18486            // ensureActivityConfigurationLocked().
18487            if (mWindowManager != null) {
18488                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18489                if (resizedStacks != null) {
18490                    for (int stackId : resizedStacks) {
18491                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18492                        mStackSupervisor.resizeStackLocked(
18493                                stackId, newBounds, null, null, false, false, !DEFER_RESUME);
18494                    }
18495                }
18496            }
18497        }
18498
18499        boolean kept = true;
18500        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18501        // mainStack is null during startup.
18502        if (mainStack != null) {
18503            if (changes != 0 && starting == null) {
18504                // If the configuration changed, and the caller is not already
18505                // in the process of starting an activity, then find the top
18506                // activity to check if its configuration needs to change.
18507                starting = mainStack.topRunningActivityLocked();
18508            }
18509
18510            if (starting != null) {
18511                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18512                // And we need to make sure at this point that all other activities
18513                // are made visible with the correct configuration.
18514                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18515                        !PRESERVE_WINDOWS);
18516            }
18517        }
18518        if (mWindowManager != null) {
18519            mWindowManager.continueSurfaceLayout();
18520        }
18521        return kept;
18522    }
18523
18524    /**
18525     * Decide based on the configuration whether we should shouw the ANR,
18526     * crash, etc dialogs.  The idea is that if there is no affordnace to
18527     * press the on-screen buttons, we shouldn't show the dialog.
18528     *
18529     * A thought: SystemUI might also want to get told about this, the Power
18530     * dialog / global actions also might want different behaviors.
18531     */
18532    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18533        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18534                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18535                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18536        final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18537                                    == Configuration.UI_MODE_TYPE_CAR);
18538        return inputMethodExists && uiIsNotCarType && !inVrMode;
18539    }
18540
18541    @Override
18542    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18543        synchronized (this) {
18544            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18545            if (srec != null) {
18546                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18547            }
18548        }
18549        return false;
18550    }
18551
18552    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18553            Intent resultData) {
18554
18555        synchronized (this) {
18556            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18557            if (r != null) {
18558                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18559            }
18560            return false;
18561        }
18562    }
18563
18564    public int getLaunchedFromUid(IBinder activityToken) {
18565        ActivityRecord srec;
18566        synchronized (this) {
18567            srec = ActivityRecord.forTokenLocked(activityToken);
18568        }
18569        if (srec == null) {
18570            return -1;
18571        }
18572        return srec.launchedFromUid;
18573    }
18574
18575    public String getLaunchedFromPackage(IBinder activityToken) {
18576        ActivityRecord srec;
18577        synchronized (this) {
18578            srec = ActivityRecord.forTokenLocked(activityToken);
18579        }
18580        if (srec == null) {
18581            return null;
18582        }
18583        return srec.launchedFromPackage;
18584    }
18585
18586    // =========================================================
18587    // LIFETIME MANAGEMENT
18588    // =========================================================
18589
18590    // Returns which broadcast queue the app is the current [or imminent] receiver
18591    // on, or 'null' if the app is not an active broadcast recipient.
18592    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18593        BroadcastRecord r = app.curReceiver;
18594        if (r != null) {
18595            return r.queue;
18596        }
18597
18598        // It's not the current receiver, but it might be starting up to become one
18599        synchronized (this) {
18600            for (BroadcastQueue queue : mBroadcastQueues) {
18601                r = queue.mPendingBroadcast;
18602                if (r != null && r.curApp == app) {
18603                    // found it; report which queue it's in
18604                    return queue;
18605                }
18606            }
18607        }
18608
18609        return null;
18610    }
18611
18612    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
18613            int targetUid, ComponentName targetComponent, String targetProcess) {
18614        if (!mTrackingAssociations) {
18615            return null;
18616        }
18617        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18618                = mAssociations.get(targetUid);
18619        if (components == null) {
18620            components = new ArrayMap<>();
18621            mAssociations.put(targetUid, components);
18622        }
18623        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18624        if (sourceUids == null) {
18625            sourceUids = new SparseArray<>();
18626            components.put(targetComponent, sourceUids);
18627        }
18628        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18629        if (sourceProcesses == null) {
18630            sourceProcesses = new ArrayMap<>();
18631            sourceUids.put(sourceUid, sourceProcesses);
18632        }
18633        Association ass = sourceProcesses.get(sourceProcess);
18634        if (ass == null) {
18635            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18636                    targetProcess);
18637            sourceProcesses.put(sourceProcess, ass);
18638        }
18639        ass.mCount++;
18640        ass.mNesting++;
18641        if (ass.mNesting == 1) {
18642            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
18643            ass.mLastState = sourceState;
18644        }
18645        return ass;
18646    }
18647
18648    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18649            ComponentName targetComponent) {
18650        if (!mTrackingAssociations) {
18651            return;
18652        }
18653        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18654                = mAssociations.get(targetUid);
18655        if (components == null) {
18656            return;
18657        }
18658        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18659        if (sourceUids == null) {
18660            return;
18661        }
18662        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18663        if (sourceProcesses == null) {
18664            return;
18665        }
18666        Association ass = sourceProcesses.get(sourceProcess);
18667        if (ass == null || ass.mNesting <= 0) {
18668            return;
18669        }
18670        ass.mNesting--;
18671        if (ass.mNesting == 0) {
18672            long uptime = SystemClock.uptimeMillis();
18673            ass.mTime += uptime - ass.mStartTime;
18674            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18675                    += uptime - ass.mLastStateUptime;
18676            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
18677        }
18678    }
18679
18680    private void noteUidProcessState(final int uid, final int state) {
18681        mBatteryStatsService.noteUidProcessState(uid, state);
18682        if (mTrackingAssociations) {
18683            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
18684                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
18685                        = mAssociations.valueAt(i1);
18686                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
18687                    SparseArray<ArrayMap<String, Association>> sourceUids
18688                            = targetComponents.valueAt(i2);
18689                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
18690                    if (sourceProcesses != null) {
18691                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
18692                            Association ass = sourceProcesses.valueAt(i4);
18693                            if (ass.mNesting >= 1) {
18694                                // currently associated
18695                                long uptime = SystemClock.uptimeMillis();
18696                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18697                                        += uptime - ass.mLastStateUptime;
18698                                ass.mLastState = state;
18699                                ass.mLastStateUptime = uptime;
18700                            }
18701                        }
18702                    }
18703                }
18704            }
18705        }
18706    }
18707
18708    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18709            boolean doingAll, long now) {
18710        if (mAdjSeq == app.adjSeq) {
18711            // This adjustment has already been computed.
18712            return app.curRawAdj;
18713        }
18714
18715        if (app.thread == null) {
18716            app.adjSeq = mAdjSeq;
18717            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18718            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18719            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18720        }
18721
18722        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18723        app.adjSource = null;
18724        app.adjTarget = null;
18725        app.empty = false;
18726        app.cached = false;
18727
18728        final int activitiesSize = app.activities.size();
18729
18730        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18731            // The max adjustment doesn't allow this app to be anything
18732            // below foreground, so it is not worth doing work for it.
18733            app.adjType = "fixed";
18734            app.adjSeq = mAdjSeq;
18735            app.curRawAdj = app.maxAdj;
18736            app.foregroundActivities = false;
18737            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18738            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18739            // System processes can do UI, and when they do we want to have
18740            // them trim their memory after the user leaves the UI.  To
18741            // facilitate this, here we need to determine whether or not it
18742            // is currently showing UI.
18743            app.systemNoUi = true;
18744            if (app == TOP_APP) {
18745                app.systemNoUi = false;
18746                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18747                app.adjType = "pers-top-activity";
18748            } else if (activitiesSize > 0) {
18749                for (int j = 0; j < activitiesSize; j++) {
18750                    final ActivityRecord r = app.activities.get(j);
18751                    if (r.visible) {
18752                        app.systemNoUi = false;
18753                    }
18754                }
18755            }
18756            if (!app.systemNoUi) {
18757                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18758            }
18759            return (app.curAdj=app.maxAdj);
18760        }
18761
18762        app.systemNoUi = false;
18763
18764        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18765
18766        // Determine the importance of the process, starting with most
18767        // important to least, and assign an appropriate OOM adjustment.
18768        int adj;
18769        int schedGroup;
18770        int procState;
18771        boolean foregroundActivities = false;
18772        BroadcastQueue queue;
18773        if (app == TOP_APP) {
18774            // The last app on the list is the foreground app.
18775            adj = ProcessList.FOREGROUND_APP_ADJ;
18776            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18777            app.adjType = "top-activity";
18778            foregroundActivities = true;
18779            procState = PROCESS_STATE_CUR_TOP;
18780        } else if (app.instrumentationClass != null) {
18781            // Don't want to kill running instrumentation.
18782            adj = ProcessList.FOREGROUND_APP_ADJ;
18783            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18784            app.adjType = "instrumentation";
18785            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18786        } else if ((queue = isReceivingBroadcast(app)) != null) {
18787            // An app that is currently receiving a broadcast also
18788            // counts as being in the foreground for OOM killer purposes.
18789            // It's placed in a sched group based on the nature of the
18790            // broadcast as reflected by which queue it's active in.
18791            adj = ProcessList.FOREGROUND_APP_ADJ;
18792            schedGroup = (queue == mFgBroadcastQueue)
18793                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18794            app.adjType = "broadcast";
18795            procState = ActivityManager.PROCESS_STATE_RECEIVER;
18796        } else if (app.executingServices.size() > 0) {
18797            // An app that is currently executing a service callback also
18798            // counts as being in the foreground.
18799            adj = ProcessList.FOREGROUND_APP_ADJ;
18800            schedGroup = app.execServicesFg ?
18801                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18802            app.adjType = "exec-service";
18803            procState = ActivityManager.PROCESS_STATE_SERVICE;
18804            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18805        } else {
18806            // As far as we know the process is empty.  We may change our mind later.
18807            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18808            // At this point we don't actually know the adjustment.  Use the cached adj
18809            // value that the caller wants us to.
18810            adj = cachedAdj;
18811            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18812            app.cached = true;
18813            app.empty = true;
18814            app.adjType = "cch-empty";
18815        }
18816
18817        // Examine all activities if not already foreground.
18818        if (!foregroundActivities && activitiesSize > 0) {
18819            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
18820            for (int j = 0; j < activitiesSize; j++) {
18821                final ActivityRecord r = app.activities.get(j);
18822                if (r.app != app) {
18823                    Log.wtf(TAG, "Found activity " + r + " in proc activity list using " + r.app
18824                            + " instead of expected " + app);
18825                    if (r.app == null || (r.app.uid == app.uid)) {
18826                        // Only fix things up when they look sane
18827                        r.app = app;
18828                    } else {
18829                        continue;
18830                    }
18831                }
18832                if (r.visible) {
18833                    // App has a visible activity; only upgrade adjustment.
18834                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18835                        adj = ProcessList.VISIBLE_APP_ADJ;
18836                        app.adjType = "visible";
18837                    }
18838                    if (procState > PROCESS_STATE_CUR_TOP) {
18839                        procState = PROCESS_STATE_CUR_TOP;
18840                    }
18841                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18842                    app.cached = false;
18843                    app.empty = false;
18844                    foregroundActivities = true;
18845                    if (r.task != null && minLayer > 0) {
18846                        final int layer = r.task.mLayerRank;
18847                        if (layer >= 0 && minLayer > layer) {
18848                            minLayer = layer;
18849                        }
18850                    }
18851                    break;
18852                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
18853                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18854                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18855                        app.adjType = "pausing";
18856                    }
18857                    if (procState > PROCESS_STATE_CUR_TOP) {
18858                        procState = PROCESS_STATE_CUR_TOP;
18859                    }
18860                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18861                    app.cached = false;
18862                    app.empty = false;
18863                    foregroundActivities = true;
18864                } else if (r.state == ActivityState.STOPPING) {
18865                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18866                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18867                        app.adjType = "stopping";
18868                    }
18869                    // For the process state, we will at this point consider the
18870                    // process to be cached.  It will be cached either as an activity
18871                    // or empty depending on whether the activity is finishing.  We do
18872                    // this so that we can treat the process as cached for purposes of
18873                    // memory trimming (determing current memory level, trim command to
18874                    // send to process) since there can be an arbitrary number of stopping
18875                    // processes and they should soon all go into the cached state.
18876                    if (!r.finishing) {
18877                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18878                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18879                        }
18880                    }
18881                    app.cached = false;
18882                    app.empty = false;
18883                    foregroundActivities = true;
18884                } else {
18885                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18886                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18887                        app.adjType = "cch-act";
18888                    }
18889                }
18890            }
18891            if (adj == ProcessList.VISIBLE_APP_ADJ) {
18892                adj += minLayer;
18893            }
18894        }
18895
18896        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
18897                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
18898            if (app.foregroundServices) {
18899                // The user is aware of this app, so make it visible.
18900                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18901                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18902                app.cached = false;
18903                app.adjType = "fg-service";
18904                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18905            } else if (app.forcingToForeground != null) {
18906                // The user is aware of this app, so make it visible.
18907                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18908                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18909                app.cached = false;
18910                app.adjType = "force-fg";
18911                app.adjSource = app.forcingToForeground;
18912                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18913            }
18914        }
18915
18916        if (app == mHeavyWeightProcess) {
18917            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18918                // We don't want to kill the current heavy-weight process.
18919                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18920                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18921                app.cached = false;
18922                app.adjType = "heavy";
18923            }
18924            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18925                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18926            }
18927        }
18928
18929        if (app == mHomeProcess) {
18930            if (adj > ProcessList.HOME_APP_ADJ) {
18931                // This process is hosting what we currently consider to be the
18932                // home app, so we don't want to let it go into the background.
18933                adj = ProcessList.HOME_APP_ADJ;
18934                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18935                app.cached = false;
18936                app.adjType = "home";
18937            }
18938            if (procState > ActivityManager.PROCESS_STATE_HOME) {
18939                procState = ActivityManager.PROCESS_STATE_HOME;
18940            }
18941        }
18942
18943        if (app == mPreviousProcess && app.activities.size() > 0) {
18944            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18945                // This was the previous process that showed UI to the user.
18946                // We want to try to keep it around more aggressively, to give
18947                // a good experience around switching between two apps.
18948                adj = ProcessList.PREVIOUS_APP_ADJ;
18949                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18950                app.cached = false;
18951                app.adjType = "previous";
18952            }
18953            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18954                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18955            }
18956        }
18957
18958        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
18959                + " reason=" + app.adjType);
18960
18961        // By default, we use the computed adjustment.  It may be changed if
18962        // there are applications dependent on our services or providers, but
18963        // this gives us a baseline and makes sure we don't get into an
18964        // infinite recursion.
18965        app.adjSeq = mAdjSeq;
18966        app.curRawAdj = adj;
18967        app.hasStartedServices = false;
18968
18969        if (mBackupTarget != null && app == mBackupTarget.app) {
18970            // If possible we want to avoid killing apps while they're being backed up
18971            if (adj > ProcessList.BACKUP_APP_ADJ) {
18972                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
18973                adj = ProcessList.BACKUP_APP_ADJ;
18974                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18975                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18976                }
18977                app.adjType = "backup";
18978                app.cached = false;
18979            }
18980            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
18981                procState = ActivityManager.PROCESS_STATE_BACKUP;
18982            }
18983        }
18984
18985        boolean mayBeTop = false;
18986
18987        for (int is = app.services.size()-1;
18988                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18989                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18990                        || procState > ActivityManager.PROCESS_STATE_TOP);
18991                is--) {
18992            ServiceRecord s = app.services.valueAt(is);
18993            if (s.startRequested) {
18994                app.hasStartedServices = true;
18995                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
18996                    procState = ActivityManager.PROCESS_STATE_SERVICE;
18997                }
18998                if (app.hasShownUi && app != mHomeProcess) {
18999                    // If this process has shown some UI, let it immediately
19000                    // go to the LRU list because it may be pretty heavy with
19001                    // UI stuff.  We'll tag it with a label just to help
19002                    // debug and understand what is going on.
19003                    if (adj > ProcessList.SERVICE_ADJ) {
19004                        app.adjType = "cch-started-ui-services";
19005                    }
19006                } else {
19007                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19008                        // This service has seen some activity within
19009                        // recent memory, so we will keep its process ahead
19010                        // of the background processes.
19011                        if (adj > ProcessList.SERVICE_ADJ) {
19012                            adj = ProcessList.SERVICE_ADJ;
19013                            app.adjType = "started-services";
19014                            app.cached = false;
19015                        }
19016                    }
19017                    // If we have let the service slide into the background
19018                    // state, still have some text describing what it is doing
19019                    // even though the service no longer has an impact.
19020                    if (adj > ProcessList.SERVICE_ADJ) {
19021                        app.adjType = "cch-started-services";
19022                    }
19023                }
19024            }
19025            for (int conni = s.connections.size()-1;
19026                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19027                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19028                            || procState > ActivityManager.PROCESS_STATE_TOP);
19029                    conni--) {
19030                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19031                for (int i = 0;
19032                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19033                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19034                                || procState > ActivityManager.PROCESS_STATE_TOP);
19035                        i++) {
19036                    // XXX should compute this based on the max of
19037                    // all connected clients.
19038                    ConnectionRecord cr = clist.get(i);
19039                    if (cr.binding.client == app) {
19040                        // Binding to ourself is not interesting.
19041                        continue;
19042                    }
19043                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19044                        ProcessRecord client = cr.binding.client;
19045                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
19046                                TOP_APP, doingAll, now);
19047                        int clientProcState = client.curProcState;
19048                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19049                            // If the other app is cached for any reason, for purposes here
19050                            // we are going to consider it empty.  The specific cached state
19051                            // doesn't propagate except under certain conditions.
19052                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19053                        }
19054                        String adjType = null;
19055                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19056                            // Not doing bind OOM management, so treat
19057                            // this guy more like a started service.
19058                            if (app.hasShownUi && app != mHomeProcess) {
19059                                // If this process has shown some UI, let it immediately
19060                                // go to the LRU list because it may be pretty heavy with
19061                                // UI stuff.  We'll tag it with a label just to help
19062                                // debug and understand what is going on.
19063                                if (adj > clientAdj) {
19064                                    adjType = "cch-bound-ui-services";
19065                                }
19066                                app.cached = false;
19067                                clientAdj = adj;
19068                                clientProcState = procState;
19069                            } else {
19070                                if (now >= (s.lastActivity
19071                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19072                                    // This service has not seen activity within
19073                                    // recent memory, so allow it to drop to the
19074                                    // LRU list if there is no other reason to keep
19075                                    // it around.  We'll also tag it with a label just
19076                                    // to help debug and undertand what is going on.
19077                                    if (adj > clientAdj) {
19078                                        adjType = "cch-bound-services";
19079                                    }
19080                                    clientAdj = adj;
19081                                }
19082                            }
19083                        }
19084                        if (adj > clientAdj) {
19085                            // If this process has recently shown UI, and
19086                            // the process that is binding to it is less
19087                            // important than being visible, then we don't
19088                            // care about the binding as much as we care
19089                            // about letting this process get into the LRU
19090                            // list to be killed and restarted if needed for
19091                            // memory.
19092                            if (app.hasShownUi && app != mHomeProcess
19093                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19094                                adjType = "cch-bound-ui-services";
19095                            } else {
19096                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19097                                        |Context.BIND_IMPORTANT)) != 0) {
19098                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19099                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19100                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19101                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19102                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19103                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19104                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19105                                    adj = clientAdj;
19106                                } else {
19107                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19108                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19109                                    }
19110                                }
19111                                if (!client.cached) {
19112                                    app.cached = false;
19113                                }
19114                                adjType = "service";
19115                            }
19116                        }
19117                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19118                            // This will treat important bound services identically to
19119                            // the top app, which may behave differently than generic
19120                            // foreground work.
19121                            if (client.curSchedGroup > schedGroup) {
19122                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19123                                    schedGroup = client.curSchedGroup;
19124                                } else {
19125                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19126                                }
19127                            }
19128                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19129                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19130                                    // Special handling of clients who are in the top state.
19131                                    // We *may* want to consider this process to be in the
19132                                    // top state as well, but only if there is not another
19133                                    // reason for it to be running.  Being on the top is a
19134                                    // special state, meaning you are specifically running
19135                                    // for the current top app.  If the process is already
19136                                    // running in the background for some other reason, it
19137                                    // is more important to continue considering it to be
19138                                    // in the background state.
19139                                    mayBeTop = true;
19140                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19141                                } else {
19142                                    // Special handling for above-top states (persistent
19143                                    // processes).  These should not bring the current process
19144                                    // into the top state, since they are not on top.  Instead
19145                                    // give them the best state after that.
19146                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19147                                        clientProcState =
19148                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19149                                    } else if (mWakefulness
19150                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19151                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19152                                                    != 0) {
19153                                        clientProcState =
19154                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19155                                    } else {
19156                                        clientProcState =
19157                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19158                                    }
19159                                }
19160                            }
19161                        } else {
19162                            if (clientProcState <
19163                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19164                                clientProcState =
19165                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19166                            }
19167                        }
19168                        if (procState > clientProcState) {
19169                            procState = clientProcState;
19170                        }
19171                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19172                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19173                            app.pendingUiClean = true;
19174                        }
19175                        if (adjType != null) {
19176                            app.adjType = adjType;
19177                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19178                                    .REASON_SERVICE_IN_USE;
19179                            app.adjSource = cr.binding.client;
19180                            app.adjSourceProcState = clientProcState;
19181                            app.adjTarget = s.name;
19182                        }
19183                    }
19184                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19185                        app.treatLikeActivity = true;
19186                    }
19187                    final ActivityRecord a = cr.activity;
19188                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19189                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19190                            (a.visible || a.state == ActivityState.RESUMED ||
19191                             a.state == ActivityState.PAUSING)) {
19192                            adj = ProcessList.FOREGROUND_APP_ADJ;
19193                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19194                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19195                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19196                                } else {
19197                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19198                                }
19199                            }
19200                            app.cached = false;
19201                            app.adjType = "service";
19202                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19203                                    .REASON_SERVICE_IN_USE;
19204                            app.adjSource = a;
19205                            app.adjSourceProcState = procState;
19206                            app.adjTarget = s.name;
19207                        }
19208                    }
19209                }
19210            }
19211        }
19212
19213        for (int provi = app.pubProviders.size()-1;
19214                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19215                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19216                        || procState > ActivityManager.PROCESS_STATE_TOP);
19217                provi--) {
19218            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19219            for (int i = cpr.connections.size()-1;
19220                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19221                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19222                            || procState > ActivityManager.PROCESS_STATE_TOP);
19223                    i--) {
19224                ContentProviderConnection conn = cpr.connections.get(i);
19225                ProcessRecord client = conn.client;
19226                if (client == app) {
19227                    // Being our own client is not interesting.
19228                    continue;
19229                }
19230                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19231                int clientProcState = client.curProcState;
19232                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19233                    // If the other app is cached for any reason, for purposes here
19234                    // we are going to consider it empty.
19235                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19236                }
19237                if (adj > clientAdj) {
19238                    if (app.hasShownUi && app != mHomeProcess
19239                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19240                        app.adjType = "cch-ui-provider";
19241                    } else {
19242                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19243                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19244                        app.adjType = "provider";
19245                    }
19246                    app.cached &= client.cached;
19247                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19248                            .REASON_PROVIDER_IN_USE;
19249                    app.adjSource = client;
19250                    app.adjSourceProcState = clientProcState;
19251                    app.adjTarget = cpr.name;
19252                }
19253                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19254                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19255                        // Special handling of clients who are in the top state.
19256                        // We *may* want to consider this process to be in the
19257                        // top state as well, but only if there is not another
19258                        // reason for it to be running.  Being on the top is a
19259                        // special state, meaning you are specifically running
19260                        // for the current top app.  If the process is already
19261                        // running in the background for some other reason, it
19262                        // is more important to continue considering it to be
19263                        // in the background state.
19264                        mayBeTop = true;
19265                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19266                    } else {
19267                        // Special handling for above-top states (persistent
19268                        // processes).  These should not bring the current process
19269                        // into the top state, since they are not on top.  Instead
19270                        // give them the best state after that.
19271                        clientProcState =
19272                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19273                    }
19274                }
19275                if (procState > clientProcState) {
19276                    procState = clientProcState;
19277                }
19278                if (client.curSchedGroup > schedGroup) {
19279                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19280                }
19281            }
19282            // If the provider has external (non-framework) process
19283            // dependencies, ensure that its adjustment is at least
19284            // FOREGROUND_APP_ADJ.
19285            if (cpr.hasExternalProcessHandles()) {
19286                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19287                    adj = ProcessList.FOREGROUND_APP_ADJ;
19288                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19289                    app.cached = false;
19290                    app.adjType = "provider";
19291                    app.adjTarget = cpr.name;
19292                }
19293                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19294                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19295                }
19296            }
19297        }
19298
19299        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19300            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19301                adj = ProcessList.PREVIOUS_APP_ADJ;
19302                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19303                app.cached = false;
19304                app.adjType = "provider";
19305            }
19306            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19307                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19308            }
19309        }
19310
19311        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19312            // A client of one of our services or providers is in the top state.  We
19313            // *may* want to be in the top state, but not if we are already running in
19314            // the background for some other reason.  For the decision here, we are going
19315            // to pick out a few specific states that we want to remain in when a client
19316            // is top (states that tend to be longer-term) and otherwise allow it to go
19317            // to the top state.
19318            switch (procState) {
19319                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19320                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19321                case ActivityManager.PROCESS_STATE_SERVICE:
19322                    // These all are longer-term states, so pull them up to the top
19323                    // of the background states, but not all the way to the top state.
19324                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19325                    break;
19326                default:
19327                    // Otherwise, top is a better choice, so take it.
19328                    procState = ActivityManager.PROCESS_STATE_TOP;
19329                    break;
19330            }
19331        }
19332
19333        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19334            if (app.hasClientActivities) {
19335                // This is a cached process, but with client activities.  Mark it so.
19336                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19337                app.adjType = "cch-client-act";
19338            } else if (app.treatLikeActivity) {
19339                // This is a cached process, but somebody wants us to treat it like it has
19340                // an activity, okay!
19341                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19342                app.adjType = "cch-as-act";
19343            }
19344        }
19345
19346        if (adj == ProcessList.SERVICE_ADJ) {
19347            if (doingAll) {
19348                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19349                mNewNumServiceProcs++;
19350                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19351                if (!app.serviceb) {
19352                    // This service isn't far enough down on the LRU list to
19353                    // normally be a B service, but if we are low on RAM and it
19354                    // is large we want to force it down since we would prefer to
19355                    // keep launcher over it.
19356                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19357                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19358                        app.serviceHighRam = true;
19359                        app.serviceb = true;
19360                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19361                    } else {
19362                        mNewNumAServiceProcs++;
19363                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19364                    }
19365                } else {
19366                    app.serviceHighRam = false;
19367                }
19368            }
19369            if (app.serviceb) {
19370                adj = ProcessList.SERVICE_B_ADJ;
19371            }
19372        }
19373
19374        app.curRawAdj = adj;
19375
19376        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19377        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19378        if (adj > app.maxAdj) {
19379            adj = app.maxAdj;
19380            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19381                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19382            }
19383        }
19384
19385        // Do final modification to adj.  Everything we do between here and applying
19386        // the final setAdj must be done in this function, because we will also use
19387        // it when computing the final cached adj later.  Note that we don't need to
19388        // worry about this for max adj above, since max adj will always be used to
19389        // keep it out of the cached vaues.
19390        app.curAdj = app.modifyRawOomAdj(adj);
19391        app.curSchedGroup = schedGroup;
19392        app.curProcState = procState;
19393        app.foregroundActivities = foregroundActivities;
19394
19395        return app.curRawAdj;
19396    }
19397
19398    /**
19399     * Record new PSS sample for a process.
19400     */
19401    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19402            long now) {
19403        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19404                swapPss * 1024);
19405        proc.lastPssTime = now;
19406        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19407        if (DEBUG_PSS) Slog.d(TAG_PSS,
19408                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19409                + " state=" + ProcessList.makeProcStateString(procState));
19410        if (proc.initialIdlePss == 0) {
19411            proc.initialIdlePss = pss;
19412        }
19413        proc.lastPss = pss;
19414        proc.lastSwapPss = swapPss;
19415        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19416            proc.lastCachedPss = pss;
19417            proc.lastCachedSwapPss = swapPss;
19418        }
19419
19420        final SparseArray<Pair<Long, String>> watchUids
19421                = mMemWatchProcesses.getMap().get(proc.processName);
19422        Long check = null;
19423        if (watchUids != null) {
19424            Pair<Long, String> val = watchUids.get(proc.uid);
19425            if (val == null) {
19426                val = watchUids.get(0);
19427            }
19428            if (val != null) {
19429                check = val.first;
19430            }
19431        }
19432        if (check != null) {
19433            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19434                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19435                if (!isDebuggable) {
19436                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19437                        isDebuggable = true;
19438                    }
19439                }
19440                if (isDebuggable) {
19441                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19442                    final ProcessRecord myProc = proc;
19443                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19444                    mMemWatchDumpProcName = proc.processName;
19445                    mMemWatchDumpFile = heapdumpFile.toString();
19446                    mMemWatchDumpPid = proc.pid;
19447                    mMemWatchDumpUid = proc.uid;
19448                    BackgroundThread.getHandler().post(new Runnable() {
19449                        @Override
19450                        public void run() {
19451                            revokeUriPermission(ActivityThread.currentActivityThread()
19452                                            .getApplicationThread(),
19453                                    DumpHeapActivity.JAVA_URI,
19454                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19455                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19456                                    UserHandle.myUserId());
19457                            ParcelFileDescriptor fd = null;
19458                            try {
19459                                heapdumpFile.delete();
19460                                fd = ParcelFileDescriptor.open(heapdumpFile,
19461                                        ParcelFileDescriptor.MODE_CREATE |
19462                                                ParcelFileDescriptor.MODE_TRUNCATE |
19463                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19464                                                ParcelFileDescriptor.MODE_APPEND);
19465                                IApplicationThread thread = myProc.thread;
19466                                if (thread != null) {
19467                                    try {
19468                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19469                                                "Requesting dump heap from "
19470                                                + myProc + " to " + heapdumpFile);
19471                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19472                                    } catch (RemoteException e) {
19473                                    }
19474                                }
19475                            } catch (FileNotFoundException e) {
19476                                e.printStackTrace();
19477                            } finally {
19478                                if (fd != null) {
19479                                    try {
19480                                        fd.close();
19481                                    } catch (IOException e) {
19482                                    }
19483                                }
19484                            }
19485                        }
19486                    });
19487                } else {
19488                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19489                            + ", but debugging not enabled");
19490                }
19491            }
19492        }
19493    }
19494
19495    /**
19496     * Schedule PSS collection of a process.
19497     */
19498    void requestPssLocked(ProcessRecord proc, int procState) {
19499        if (mPendingPssProcesses.contains(proc)) {
19500            return;
19501        }
19502        if (mPendingPssProcesses.size() == 0) {
19503            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19504        }
19505        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19506        proc.pssProcState = procState;
19507        mPendingPssProcesses.add(proc);
19508    }
19509
19510    /**
19511     * Schedule PSS collection of all processes.
19512     */
19513    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19514        if (!always) {
19515            if (now < (mLastFullPssTime +
19516                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19517                return;
19518            }
19519        }
19520        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19521        mLastFullPssTime = now;
19522        mFullPssPending = true;
19523        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19524        mPendingPssProcesses.clear();
19525        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19526            ProcessRecord app = mLruProcesses.get(i);
19527            if (app.thread == null
19528                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19529                continue;
19530            }
19531            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19532                app.pssProcState = app.setProcState;
19533                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19534                        mTestPssMode, isSleeping(), now);
19535                mPendingPssProcesses.add(app);
19536            }
19537        }
19538        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19539    }
19540
19541    public void setTestPssMode(boolean enabled) {
19542        synchronized (this) {
19543            mTestPssMode = enabled;
19544            if (enabled) {
19545                // Whenever we enable the mode, we want to take a snapshot all of current
19546                // process mem use.
19547                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19548            }
19549        }
19550    }
19551
19552    /**
19553     * Ask a given process to GC right now.
19554     */
19555    final void performAppGcLocked(ProcessRecord app) {
19556        try {
19557            app.lastRequestedGc = SystemClock.uptimeMillis();
19558            if (app.thread != null) {
19559                if (app.reportLowMemory) {
19560                    app.reportLowMemory = false;
19561                    app.thread.scheduleLowMemory();
19562                } else {
19563                    app.thread.processInBackground();
19564                }
19565            }
19566        } catch (Exception e) {
19567            // whatever.
19568        }
19569    }
19570
19571    /**
19572     * Returns true if things are idle enough to perform GCs.
19573     */
19574    private final boolean canGcNowLocked() {
19575        boolean processingBroadcasts = false;
19576        for (BroadcastQueue q : mBroadcastQueues) {
19577            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19578                processingBroadcasts = true;
19579            }
19580        }
19581        return !processingBroadcasts
19582                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19583    }
19584
19585    /**
19586     * Perform GCs on all processes that are waiting for it, but only
19587     * if things are idle.
19588     */
19589    final void performAppGcsLocked() {
19590        final int N = mProcessesToGc.size();
19591        if (N <= 0) {
19592            return;
19593        }
19594        if (canGcNowLocked()) {
19595            while (mProcessesToGc.size() > 0) {
19596                ProcessRecord proc = mProcessesToGc.remove(0);
19597                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19598                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19599                            <= SystemClock.uptimeMillis()) {
19600                        // To avoid spamming the system, we will GC processes one
19601                        // at a time, waiting a few seconds between each.
19602                        performAppGcLocked(proc);
19603                        scheduleAppGcsLocked();
19604                        return;
19605                    } else {
19606                        // It hasn't been long enough since we last GCed this
19607                        // process...  put it in the list to wait for its time.
19608                        addProcessToGcListLocked(proc);
19609                        break;
19610                    }
19611                }
19612            }
19613
19614            scheduleAppGcsLocked();
19615        }
19616    }
19617
19618    /**
19619     * If all looks good, perform GCs on all processes waiting for them.
19620     */
19621    final void performAppGcsIfAppropriateLocked() {
19622        if (canGcNowLocked()) {
19623            performAppGcsLocked();
19624            return;
19625        }
19626        // Still not idle, wait some more.
19627        scheduleAppGcsLocked();
19628    }
19629
19630    /**
19631     * Schedule the execution of all pending app GCs.
19632     */
19633    final void scheduleAppGcsLocked() {
19634        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19635
19636        if (mProcessesToGc.size() > 0) {
19637            // Schedule a GC for the time to the next process.
19638            ProcessRecord proc = mProcessesToGc.get(0);
19639            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19640
19641            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19642            long now = SystemClock.uptimeMillis();
19643            if (when < (now+GC_TIMEOUT)) {
19644                when = now + GC_TIMEOUT;
19645            }
19646            mHandler.sendMessageAtTime(msg, when);
19647        }
19648    }
19649
19650    /**
19651     * Add a process to the array of processes waiting to be GCed.  Keeps the
19652     * list in sorted order by the last GC time.  The process can't already be
19653     * on the list.
19654     */
19655    final void addProcessToGcListLocked(ProcessRecord proc) {
19656        boolean added = false;
19657        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19658            if (mProcessesToGc.get(i).lastRequestedGc <
19659                    proc.lastRequestedGc) {
19660                added = true;
19661                mProcessesToGc.add(i+1, proc);
19662                break;
19663            }
19664        }
19665        if (!added) {
19666            mProcessesToGc.add(0, proc);
19667        }
19668    }
19669
19670    /**
19671     * Set up to ask a process to GC itself.  This will either do it
19672     * immediately, or put it on the list of processes to gc the next
19673     * time things are idle.
19674     */
19675    final void scheduleAppGcLocked(ProcessRecord app) {
19676        long now = SystemClock.uptimeMillis();
19677        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19678            return;
19679        }
19680        if (!mProcessesToGc.contains(app)) {
19681            addProcessToGcListLocked(app);
19682            scheduleAppGcsLocked();
19683        }
19684    }
19685
19686    final void checkExcessivePowerUsageLocked(boolean doKills) {
19687        updateCpuStatsNow();
19688
19689        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19690        boolean doWakeKills = doKills;
19691        boolean doCpuKills = doKills;
19692        if (mLastPowerCheckRealtime == 0) {
19693            doWakeKills = false;
19694        }
19695        if (mLastPowerCheckUptime == 0) {
19696            doCpuKills = false;
19697        }
19698        if (stats.isScreenOn()) {
19699            doWakeKills = false;
19700        }
19701        final long curRealtime = SystemClock.elapsedRealtime();
19702        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19703        final long curUptime = SystemClock.uptimeMillis();
19704        final long uptimeSince = curUptime - mLastPowerCheckUptime;
19705        mLastPowerCheckRealtime = curRealtime;
19706        mLastPowerCheckUptime = curUptime;
19707        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19708            doWakeKills = false;
19709        }
19710        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19711            doCpuKills = false;
19712        }
19713        int i = mLruProcesses.size();
19714        while (i > 0) {
19715            i--;
19716            ProcessRecord app = mLruProcesses.get(i);
19717            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19718                long wtime;
19719                synchronized (stats) {
19720                    wtime = stats.getProcessWakeTime(app.info.uid,
19721                            app.pid, curRealtime);
19722                }
19723                long wtimeUsed = wtime - app.lastWakeTime;
19724                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19725                if (DEBUG_POWER) {
19726                    StringBuilder sb = new StringBuilder(128);
19727                    sb.append("Wake for ");
19728                    app.toShortString(sb);
19729                    sb.append(": over ");
19730                    TimeUtils.formatDuration(realtimeSince, sb);
19731                    sb.append(" used ");
19732                    TimeUtils.formatDuration(wtimeUsed, sb);
19733                    sb.append(" (");
19734                    sb.append((wtimeUsed*100)/realtimeSince);
19735                    sb.append("%)");
19736                    Slog.i(TAG_POWER, sb.toString());
19737                    sb.setLength(0);
19738                    sb.append("CPU for ");
19739                    app.toShortString(sb);
19740                    sb.append(": over ");
19741                    TimeUtils.formatDuration(uptimeSince, sb);
19742                    sb.append(" used ");
19743                    TimeUtils.formatDuration(cputimeUsed, sb);
19744                    sb.append(" (");
19745                    sb.append((cputimeUsed*100)/uptimeSince);
19746                    sb.append("%)");
19747                    Slog.i(TAG_POWER, sb.toString());
19748                }
19749                // If a process has held a wake lock for more
19750                // than 50% of the time during this period,
19751                // that sounds bad.  Kill!
19752                if (doWakeKills && realtimeSince > 0
19753                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
19754                    synchronized (stats) {
19755                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19756                                realtimeSince, wtimeUsed);
19757                    }
19758                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19759                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19760                } else if (doCpuKills && uptimeSince > 0
19761                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
19762                    synchronized (stats) {
19763                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19764                                uptimeSince, cputimeUsed);
19765                    }
19766                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19767                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19768                } else {
19769                    app.lastWakeTime = wtime;
19770                    app.lastCpuTime = app.curCpuTime;
19771                }
19772            }
19773        }
19774    }
19775
19776    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19777            long nowElapsed) {
19778        boolean success = true;
19779
19780        if (app.curRawAdj != app.setRawAdj) {
19781            app.setRawAdj = app.curRawAdj;
19782        }
19783
19784        int changes = 0;
19785
19786        if (app.curAdj != app.setAdj) {
19787            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19788            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19789                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19790                    + app.adjType);
19791            app.setAdj = app.curAdj;
19792        }
19793
19794        if (app.setSchedGroup != app.curSchedGroup) {
19795            app.setSchedGroup = app.curSchedGroup;
19796            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19797                    "Setting sched group of " + app.processName
19798                    + " to " + app.curSchedGroup);
19799            if (app.waitingToKill != null && app.curReceiver == null
19800                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
19801                app.kill(app.waitingToKill, true);
19802                success = false;
19803            } else {
19804                int processGroup;
19805                switch (app.curSchedGroup) {
19806                    case ProcessList.SCHED_GROUP_BACKGROUND:
19807                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
19808                        break;
19809                    case ProcessList.SCHED_GROUP_TOP_APP:
19810                        processGroup = Process.THREAD_GROUP_TOP_APP;
19811                        break;
19812                    default:
19813                        processGroup = Process.THREAD_GROUP_DEFAULT;
19814                        break;
19815                }
19816                if (true) {
19817                    long oldId = Binder.clearCallingIdentity();
19818                    try {
19819                        Process.setProcessGroup(app.pid, processGroup);
19820                    } catch (Exception e) {
19821                        Slog.w(TAG, "Failed setting process group of " + app.pid
19822                                + " to " + app.curSchedGroup);
19823                        e.printStackTrace();
19824                    } finally {
19825                        Binder.restoreCallingIdentity(oldId);
19826                    }
19827                } else {
19828                    if (app.thread != null) {
19829                        try {
19830                            app.thread.setSchedulingGroup(processGroup);
19831                        } catch (RemoteException e) {
19832                        }
19833                    }
19834                }
19835            }
19836        }
19837        if (app.repForegroundActivities != app.foregroundActivities) {
19838            app.repForegroundActivities = app.foregroundActivities;
19839            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
19840        }
19841        if (app.repProcState != app.curProcState) {
19842            app.repProcState = app.curProcState;
19843            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
19844            if (app.thread != null) {
19845                try {
19846                    if (false) {
19847                        //RuntimeException h = new RuntimeException("here");
19848                        Slog.i(TAG, "Sending new process state " + app.repProcState
19849                                + " to " + app /*, h*/);
19850                    }
19851                    app.thread.setProcessState(app.repProcState);
19852                } catch (RemoteException e) {
19853                }
19854            }
19855        }
19856        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
19857                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
19858            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
19859                // Experimental code to more aggressively collect pss while
19860                // running test...  the problem is that this tends to collect
19861                // the data right when a process is transitioning between process
19862                // states, which well tend to give noisy data.
19863                long start = SystemClock.uptimeMillis();
19864                long pss = Debug.getPss(app.pid, mTmpLong, null);
19865                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
19866                mPendingPssProcesses.remove(app);
19867                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
19868                        + " to " + app.curProcState + ": "
19869                        + (SystemClock.uptimeMillis()-start) + "ms");
19870            }
19871            app.lastStateTime = now;
19872            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19873                    mTestPssMode, isSleeping(), now);
19874            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
19875                    + ProcessList.makeProcStateString(app.setProcState) + " to "
19876                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
19877                    + (app.nextPssTime-now) + ": " + app);
19878        } else {
19879            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
19880                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
19881                    mTestPssMode)))) {
19882                requestPssLocked(app, app.setProcState);
19883                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
19884                        mTestPssMode, isSleeping(), now);
19885            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
19886                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
19887        }
19888        if (app.setProcState != app.curProcState) {
19889            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19890                    "Proc state change of " + app.processName
19891                            + " to " + app.curProcState);
19892            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
19893            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
19894            if (setImportant && !curImportant) {
19895                // This app is no longer something we consider important enough to allow to
19896                // use arbitrary amounts of battery power.  Note
19897                // its current wake lock time to later know to kill it if
19898                // it is not behaving well.
19899                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19900                synchronized (stats) {
19901                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
19902                            app.pid, nowElapsed);
19903                }
19904                app.lastCpuTime = app.curCpuTime;
19905
19906            }
19907            // Inform UsageStats of important process state change
19908            // Must be called before updating setProcState
19909            maybeUpdateUsageStatsLocked(app, nowElapsed);
19910
19911            app.setProcState = app.curProcState;
19912            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19913                app.notCachedSinceIdle = false;
19914            }
19915            if (!doingAll) {
19916                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
19917            } else {
19918                app.procStateChanged = true;
19919            }
19920        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
19921                > USAGE_STATS_INTERACTION_INTERVAL) {
19922            // For apps that sit around for a long time in the interactive state, we need
19923            // to report this at least once a day so they don't go idle.
19924            maybeUpdateUsageStatsLocked(app, nowElapsed);
19925        }
19926
19927        if (changes != 0) {
19928            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19929                    "Changes in " + app + ": " + changes);
19930            int i = mPendingProcessChanges.size()-1;
19931            ProcessChangeItem item = null;
19932            while (i >= 0) {
19933                item = mPendingProcessChanges.get(i);
19934                if (item.pid == app.pid) {
19935                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19936                            "Re-using existing item: " + item);
19937                    break;
19938                }
19939                i--;
19940            }
19941            if (i < 0) {
19942                // No existing item in pending changes; need a new one.
19943                final int NA = mAvailProcessChanges.size();
19944                if (NA > 0) {
19945                    item = mAvailProcessChanges.remove(NA-1);
19946                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19947                            "Retrieving available item: " + item);
19948                } else {
19949                    item = new ProcessChangeItem();
19950                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19951                            "Allocating new item: " + item);
19952                }
19953                item.changes = 0;
19954                item.pid = app.pid;
19955                item.uid = app.info.uid;
19956                if (mPendingProcessChanges.size() == 0) {
19957                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19958                            "*** Enqueueing dispatch processes changed!");
19959                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
19960                }
19961                mPendingProcessChanges.add(item);
19962            }
19963            item.changes |= changes;
19964            item.processState = app.repProcState;
19965            item.foregroundActivities = app.repForegroundActivities;
19966            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19967                    "Item " + Integer.toHexString(System.identityHashCode(item))
19968                    + " " + app.toShortString() + ": changes=" + item.changes
19969                    + " procState=" + item.processState
19970                    + " foreground=" + item.foregroundActivities
19971                    + " type=" + app.adjType + " source=" + app.adjSource
19972                    + " target=" + app.adjTarget);
19973        }
19974
19975        return success;
19976    }
19977
19978    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
19979        final UidRecord.ChangeItem pendingChange;
19980        if (uidRec == null || uidRec.pendingChange == null) {
19981            if (mPendingUidChanges.size() == 0) {
19982                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19983                        "*** Enqueueing dispatch uid changed!");
19984                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
19985            }
19986            final int NA = mAvailUidChanges.size();
19987            if (NA > 0) {
19988                pendingChange = mAvailUidChanges.remove(NA-1);
19989                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19990                        "Retrieving available item: " + pendingChange);
19991            } else {
19992                pendingChange = new UidRecord.ChangeItem();
19993                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19994                        "Allocating new item: " + pendingChange);
19995            }
19996            if (uidRec != null) {
19997                uidRec.pendingChange = pendingChange;
19998                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
19999                    // If this uid is going away, and we haven't yet reported it is gone,
20000                    // then do so now.
20001                    change = UidRecord.CHANGE_GONE_IDLE;
20002                }
20003            } else if (uid < 0) {
20004                throw new IllegalArgumentException("No UidRecord or uid");
20005            }
20006            pendingChange.uidRecord = uidRec;
20007            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20008            mPendingUidChanges.add(pendingChange);
20009        } else {
20010            pendingChange = uidRec.pendingChange;
20011            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20012                change = UidRecord.CHANGE_GONE_IDLE;
20013            }
20014        }
20015        pendingChange.change = change;
20016        pendingChange.processState = uidRec != null
20017                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20018    }
20019
20020    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20021            String authority) {
20022        if (app == null) return;
20023        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20024            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20025            if (userState == null) return;
20026            final long now = SystemClock.elapsedRealtime();
20027            Long lastReported = userState.mProviderLastReportedFg.get(authority);
20028            if (lastReported == null || lastReported < now - 60 * 1000L) {
20029                mUsageStatsService.reportContentProviderUsage(
20030                        authority, providerPkgName, app.userId);
20031                userState.mProviderLastReportedFg.put(authority, now);
20032            }
20033        }
20034    }
20035
20036    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20037        if (DEBUG_USAGE_STATS) {
20038            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20039                    + "] state changes: old = " + app.setProcState + ", new = "
20040                    + app.curProcState);
20041        }
20042        if (mUsageStatsService == null) {
20043            return;
20044        }
20045        boolean isInteraction;
20046        // To avoid some abuse patterns, we are going to be careful about what we consider
20047        // to be an app interaction.  Being the top activity doesn't count while the display
20048        // is sleeping, nor do short foreground services.
20049        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20050            isInteraction = true;
20051            app.fgInteractionTime = 0;
20052        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20053            if (app.fgInteractionTime == 0) {
20054                app.fgInteractionTime = nowElapsed;
20055                isInteraction = false;
20056            } else {
20057                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20058            }
20059        } else {
20060            isInteraction = app.curProcState
20061                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20062            app.fgInteractionTime = 0;
20063        }
20064        if (isInteraction && (!app.reportedInteraction
20065                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20066            app.interactionEventTime = nowElapsed;
20067            String[] packages = app.getPackageList();
20068            if (packages != null) {
20069                for (int i = 0; i < packages.length; i++) {
20070                    mUsageStatsService.reportEvent(packages[i], app.userId,
20071                            UsageEvents.Event.SYSTEM_INTERACTION);
20072                }
20073            }
20074        }
20075        app.reportedInteraction = isInteraction;
20076        if (!isInteraction) {
20077            app.interactionEventTime = 0;
20078        }
20079    }
20080
20081    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20082        if (proc.thread != null) {
20083            if (proc.baseProcessTracker != null) {
20084                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20085            }
20086        }
20087    }
20088
20089    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20090            ProcessRecord TOP_APP, boolean doingAll, long now) {
20091        if (app.thread == null) {
20092            return false;
20093        }
20094
20095        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20096
20097        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20098    }
20099
20100    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20101            boolean oomAdj) {
20102        if (isForeground != proc.foregroundServices) {
20103            proc.foregroundServices = isForeground;
20104            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20105                    proc.info.uid);
20106            if (isForeground) {
20107                if (curProcs == null) {
20108                    curProcs = new ArrayList<ProcessRecord>();
20109                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20110                }
20111                if (!curProcs.contains(proc)) {
20112                    curProcs.add(proc);
20113                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20114                            proc.info.packageName, proc.info.uid);
20115                }
20116            } else {
20117                if (curProcs != null) {
20118                    if (curProcs.remove(proc)) {
20119                        mBatteryStatsService.noteEvent(
20120                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20121                                proc.info.packageName, proc.info.uid);
20122                        if (curProcs.size() <= 0) {
20123                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20124                        }
20125                    }
20126                }
20127            }
20128            if (oomAdj) {
20129                updateOomAdjLocked();
20130            }
20131        }
20132    }
20133
20134    private final ActivityRecord resumedAppLocked() {
20135        ActivityRecord act = mStackSupervisor.resumedAppLocked();
20136        String pkg;
20137        int uid;
20138        if (act != null) {
20139            pkg = act.packageName;
20140            uid = act.info.applicationInfo.uid;
20141        } else {
20142            pkg = null;
20143            uid = -1;
20144        }
20145        // Has the UID or resumed package name changed?
20146        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20147                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20148            if (mCurResumedPackage != null) {
20149                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20150                        mCurResumedPackage, mCurResumedUid);
20151            }
20152            mCurResumedPackage = pkg;
20153            mCurResumedUid = uid;
20154            if (mCurResumedPackage != null) {
20155                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20156                        mCurResumedPackage, mCurResumedUid);
20157            }
20158        }
20159        return act;
20160    }
20161
20162    final boolean updateOomAdjLocked(ProcessRecord app) {
20163        final ActivityRecord TOP_ACT = resumedAppLocked();
20164        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20165        final boolean wasCached = app.cached;
20166
20167        mAdjSeq++;
20168
20169        // This is the desired cached adjusment we want to tell it to use.
20170        // If our app is currently cached, we know it, and that is it.  Otherwise,
20171        // we don't know it yet, and it needs to now be cached we will then
20172        // need to do a complete oom adj.
20173        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20174                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20175        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20176                SystemClock.uptimeMillis());
20177        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20178            // Changed to/from cached state, so apps after it in the LRU
20179            // list may also be changed.
20180            updateOomAdjLocked();
20181        }
20182        return success;
20183    }
20184
20185    final void updateOomAdjLocked() {
20186        final ActivityRecord TOP_ACT = resumedAppLocked();
20187        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20188        final long now = SystemClock.uptimeMillis();
20189        final long nowElapsed = SystemClock.elapsedRealtime();
20190        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20191        final int N = mLruProcesses.size();
20192
20193        if (false) {
20194            RuntimeException e = new RuntimeException();
20195            e.fillInStackTrace();
20196            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20197        }
20198
20199        // Reset state in all uid records.
20200        for (int i=mActiveUids.size()-1; i>=0; i--) {
20201            final UidRecord uidRec = mActiveUids.valueAt(i);
20202            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20203                    "Starting update of " + uidRec);
20204            uidRec.reset();
20205        }
20206
20207        mStackSupervisor.rankTaskLayersIfNeeded();
20208
20209        mAdjSeq++;
20210        mNewNumServiceProcs = 0;
20211        mNewNumAServiceProcs = 0;
20212
20213        final int emptyProcessLimit;
20214        final int cachedProcessLimit;
20215        if (mProcessLimit <= 0) {
20216            emptyProcessLimit = cachedProcessLimit = 0;
20217        } else if (mProcessLimit == 1) {
20218            emptyProcessLimit = 1;
20219            cachedProcessLimit = 0;
20220        } else {
20221            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20222            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20223        }
20224
20225        // Let's determine how many processes we have running vs.
20226        // how many slots we have for background processes; we may want
20227        // to put multiple processes in a slot of there are enough of
20228        // them.
20229        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20230                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20231        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20232        if (numEmptyProcs > cachedProcessLimit) {
20233            // If there are more empty processes than our limit on cached
20234            // processes, then use the cached process limit for the factor.
20235            // This ensures that the really old empty processes get pushed
20236            // down to the bottom, so if we are running low on memory we will
20237            // have a better chance at keeping around more cached processes
20238            // instead of a gazillion empty processes.
20239            numEmptyProcs = cachedProcessLimit;
20240        }
20241        int emptyFactor = numEmptyProcs/numSlots;
20242        if (emptyFactor < 1) emptyFactor = 1;
20243        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20244        if (cachedFactor < 1) cachedFactor = 1;
20245        int stepCached = 0;
20246        int stepEmpty = 0;
20247        int numCached = 0;
20248        int numEmpty = 0;
20249        int numTrimming = 0;
20250
20251        mNumNonCachedProcs = 0;
20252        mNumCachedHiddenProcs = 0;
20253
20254        // First update the OOM adjustment for each of the
20255        // application processes based on their current state.
20256        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20257        int nextCachedAdj = curCachedAdj+1;
20258        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20259        int nextEmptyAdj = curEmptyAdj+2;
20260        for (int i=N-1; i>=0; i--) {
20261            ProcessRecord app = mLruProcesses.get(i);
20262            if (!app.killedByAm && app.thread != null) {
20263                app.procStateChanged = false;
20264                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20265
20266                // If we haven't yet assigned the final cached adj
20267                // to the process, do that now.
20268                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20269                    switch (app.curProcState) {
20270                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20271                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20272                            // This process is a cached process holding activities...
20273                            // assign it the next cached value for that type, and then
20274                            // step that cached level.
20275                            app.curRawAdj = curCachedAdj;
20276                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20277                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20278                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20279                                    + ")");
20280                            if (curCachedAdj != nextCachedAdj) {
20281                                stepCached++;
20282                                if (stepCached >= cachedFactor) {
20283                                    stepCached = 0;
20284                                    curCachedAdj = nextCachedAdj;
20285                                    nextCachedAdj += 2;
20286                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20287                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20288                                    }
20289                                }
20290                            }
20291                            break;
20292                        default:
20293                            // For everything else, assign next empty cached process
20294                            // level and bump that up.  Note that this means that
20295                            // long-running services that have dropped down to the
20296                            // cached level will be treated as empty (since their process
20297                            // state is still as a service), which is what we want.
20298                            app.curRawAdj = curEmptyAdj;
20299                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20300                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20301                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20302                                    + ")");
20303                            if (curEmptyAdj != nextEmptyAdj) {
20304                                stepEmpty++;
20305                                if (stepEmpty >= emptyFactor) {
20306                                    stepEmpty = 0;
20307                                    curEmptyAdj = nextEmptyAdj;
20308                                    nextEmptyAdj += 2;
20309                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20310                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20311                                    }
20312                                }
20313                            }
20314                            break;
20315                    }
20316                }
20317
20318                applyOomAdjLocked(app, true, now, nowElapsed);
20319
20320                // Count the number of process types.
20321                switch (app.curProcState) {
20322                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20323                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20324                        mNumCachedHiddenProcs++;
20325                        numCached++;
20326                        if (numCached > cachedProcessLimit) {
20327                            app.kill("cached #" + numCached, true);
20328                        }
20329                        break;
20330                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20331                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20332                                && app.lastActivityTime < oldTime) {
20333                            app.kill("empty for "
20334                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20335                                    / 1000) + "s", true);
20336                        } else {
20337                            numEmpty++;
20338                            if (numEmpty > emptyProcessLimit) {
20339                                app.kill("empty #" + numEmpty, true);
20340                            }
20341                        }
20342                        break;
20343                    default:
20344                        mNumNonCachedProcs++;
20345                        break;
20346                }
20347
20348                if (app.isolated && app.services.size() <= 0) {
20349                    // If this is an isolated process, and there are no
20350                    // services running in it, then the process is no longer
20351                    // needed.  We agressively kill these because we can by
20352                    // definition not re-use the same process again, and it is
20353                    // good to avoid having whatever code was running in them
20354                    // left sitting around after no longer needed.
20355                    app.kill("isolated not needed", true);
20356                } else {
20357                    // Keeping this process, update its uid.
20358                    final UidRecord uidRec = app.uidRecord;
20359                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20360                        uidRec.curProcState = app.curProcState;
20361                    }
20362                }
20363
20364                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20365                        && !app.killedByAm) {
20366                    numTrimming++;
20367                }
20368            }
20369        }
20370
20371        mNumServiceProcs = mNewNumServiceProcs;
20372
20373        // Now determine the memory trimming level of background processes.
20374        // Unfortunately we need to start at the back of the list to do this
20375        // properly.  We only do this if the number of background apps we
20376        // are managing to keep around is less than half the maximum we desire;
20377        // if we are keeping a good number around, we'll let them use whatever
20378        // memory they want.
20379        final int numCachedAndEmpty = numCached + numEmpty;
20380        int memFactor;
20381        if (numCached <= ProcessList.TRIM_CACHED_APPS
20382                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20383            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20384                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20385            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20386                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20387            } else {
20388                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20389            }
20390        } else {
20391            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20392        }
20393        // We always allow the memory level to go up (better).  We only allow it to go
20394        // down if we are in a state where that is allowed, *and* the total number of processes
20395        // has gone down since last time.
20396        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20397                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20398                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20399        if (memFactor > mLastMemoryLevel) {
20400            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20401                memFactor = mLastMemoryLevel;
20402                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20403            }
20404        }
20405        if (memFactor != mLastMemoryLevel) {
20406            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20407        }
20408        mLastMemoryLevel = memFactor;
20409        mLastNumProcesses = mLruProcesses.size();
20410        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
20411        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20412        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20413            if (mLowRamStartTime == 0) {
20414                mLowRamStartTime = now;
20415            }
20416            int step = 0;
20417            int fgTrimLevel;
20418            switch (memFactor) {
20419                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20420                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20421                    break;
20422                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20423                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20424                    break;
20425                default:
20426                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20427                    break;
20428            }
20429            int factor = numTrimming/3;
20430            int minFactor = 2;
20431            if (mHomeProcess != null) minFactor++;
20432            if (mPreviousProcess != null) minFactor++;
20433            if (factor < minFactor) factor = minFactor;
20434            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20435            for (int i=N-1; i>=0; i--) {
20436                ProcessRecord app = mLruProcesses.get(i);
20437                if (allChanged || app.procStateChanged) {
20438                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20439                    app.procStateChanged = false;
20440                }
20441                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20442                        && !app.killedByAm) {
20443                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20444                        try {
20445                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20446                                    "Trimming memory of " + app.processName + " to " + curLevel);
20447                            app.thread.scheduleTrimMemory(curLevel);
20448                        } catch (RemoteException e) {
20449                        }
20450                        if (false) {
20451                            // For now we won't do this; our memory trimming seems
20452                            // to be good enough at this point that destroying
20453                            // activities causes more harm than good.
20454                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20455                                    && app != mHomeProcess && app != mPreviousProcess) {
20456                                // Need to do this on its own message because the stack may not
20457                                // be in a consistent state at this point.
20458                                // For these apps we will also finish their activities
20459                                // to help them free memory.
20460                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20461                            }
20462                        }
20463                    }
20464                    app.trimMemoryLevel = curLevel;
20465                    step++;
20466                    if (step >= factor) {
20467                        step = 0;
20468                        switch (curLevel) {
20469                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20470                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20471                                break;
20472                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20473                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20474                                break;
20475                        }
20476                    }
20477                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20478                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20479                            && app.thread != null) {
20480                        try {
20481                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20482                                    "Trimming memory of heavy-weight " + app.processName
20483                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20484                            app.thread.scheduleTrimMemory(
20485                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20486                        } catch (RemoteException e) {
20487                        }
20488                    }
20489                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20490                } else {
20491                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20492                            || app.systemNoUi) && app.pendingUiClean) {
20493                        // If this application is now in the background and it
20494                        // had done UI, then give it the special trim level to
20495                        // have it free UI resources.
20496                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20497                        if (app.trimMemoryLevel < level && app.thread != null) {
20498                            try {
20499                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20500                                        "Trimming memory of bg-ui " + app.processName
20501                                        + " to " + level);
20502                                app.thread.scheduleTrimMemory(level);
20503                            } catch (RemoteException e) {
20504                            }
20505                        }
20506                        app.pendingUiClean = false;
20507                    }
20508                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20509                        try {
20510                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20511                                    "Trimming memory of fg " + app.processName
20512                                    + " to " + fgTrimLevel);
20513                            app.thread.scheduleTrimMemory(fgTrimLevel);
20514                        } catch (RemoteException e) {
20515                        }
20516                    }
20517                    app.trimMemoryLevel = fgTrimLevel;
20518                }
20519            }
20520        } else {
20521            if (mLowRamStartTime != 0) {
20522                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20523                mLowRamStartTime = 0;
20524            }
20525            for (int i=N-1; i>=0; i--) {
20526                ProcessRecord app = mLruProcesses.get(i);
20527                if (allChanged || app.procStateChanged) {
20528                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20529                    app.procStateChanged = false;
20530                }
20531                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20532                        || app.systemNoUi) && app.pendingUiClean) {
20533                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20534                            && app.thread != null) {
20535                        try {
20536                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20537                                    "Trimming memory of ui hidden " + app.processName
20538                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20539                            app.thread.scheduleTrimMemory(
20540                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20541                        } catch (RemoteException e) {
20542                        }
20543                    }
20544                    app.pendingUiClean = false;
20545                }
20546                app.trimMemoryLevel = 0;
20547            }
20548        }
20549
20550        if (mAlwaysFinishActivities) {
20551            // Need to do this on its own message because the stack may not
20552            // be in a consistent state at this point.
20553            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20554        }
20555
20556        if (allChanged) {
20557            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20558        }
20559
20560        // Update from any uid changes.
20561        for (int i=mActiveUids.size()-1; i>=0; i--) {
20562            final UidRecord uidRec = mActiveUids.valueAt(i);
20563            int uidChange = UidRecord.CHANGE_PROCSTATE;
20564            if (uidRec.setProcState != uidRec.curProcState) {
20565                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20566                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20567                        + " to " + uidRec.curProcState);
20568                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20569                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20570                        uidRec.lastBackgroundTime = nowElapsed;
20571                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20572                            // Note: the background settle time is in elapsed realtime, while
20573                            // the handler time base is uptime.  All this means is that we may
20574                            // stop background uids later than we had intended, but that only
20575                            // happens because the device was sleeping so we are okay anyway.
20576                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20577                        }
20578                    }
20579                } else {
20580                    if (uidRec.idle) {
20581                        uidChange = UidRecord.CHANGE_ACTIVE;
20582                        uidRec.idle = false;
20583                    }
20584                    uidRec.lastBackgroundTime = 0;
20585                }
20586                uidRec.setProcState = uidRec.curProcState;
20587                enqueueUidChangeLocked(uidRec, -1, uidChange);
20588                noteUidProcessState(uidRec.uid, uidRec.curProcState);
20589            }
20590        }
20591
20592        if (mProcessStats.shouldWriteNowLocked(now)) {
20593            mHandler.post(new Runnable() {
20594                @Override public void run() {
20595                    synchronized (ActivityManagerService.this) {
20596                        mProcessStats.writeStateAsyncLocked();
20597                    }
20598                }
20599            });
20600        }
20601
20602        if (DEBUG_OOM_ADJ) {
20603            final long duration = SystemClock.uptimeMillis() - now;
20604            if (false) {
20605                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20606                        new RuntimeException("here").fillInStackTrace());
20607            } else {
20608                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20609            }
20610        }
20611    }
20612
20613    final void idleUids() {
20614        synchronized (this) {
20615            final long nowElapsed = SystemClock.elapsedRealtime();
20616            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20617            long nextTime = 0;
20618            for (int i=mActiveUids.size()-1; i>=0; i--) {
20619                final UidRecord uidRec = mActiveUids.valueAt(i);
20620                final long bgTime = uidRec.lastBackgroundTime;
20621                if (bgTime > 0 && !uidRec.idle) {
20622                    if (bgTime <= maxBgTime) {
20623                        uidRec.idle = true;
20624                        doStopUidLocked(uidRec.uid, uidRec);
20625                    } else {
20626                        if (nextTime == 0 || nextTime > bgTime) {
20627                            nextTime = bgTime;
20628                        }
20629                    }
20630                }
20631            }
20632            if (nextTime > 0) {
20633                mHandler.removeMessages(IDLE_UIDS_MSG);
20634                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20635                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20636            }
20637        }
20638    }
20639
20640    final void runInBackgroundDisabled(int uid) {
20641        synchronized (this) {
20642            UidRecord uidRec = mActiveUids.get(uid);
20643            if (uidRec != null) {
20644                // This uid is actually running...  should it be considered background now?
20645                if (uidRec.idle) {
20646                    doStopUidLocked(uidRec.uid, uidRec);
20647                }
20648            } else {
20649                // This uid isn't actually running...  still send a report about it being "stopped".
20650                doStopUidLocked(uid, null);
20651            }
20652        }
20653    }
20654
20655    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20656        mServices.stopInBackgroundLocked(uid);
20657        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20658    }
20659
20660    final void trimApplications() {
20661        synchronized (this) {
20662            int i;
20663
20664            // First remove any unused application processes whose package
20665            // has been removed.
20666            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20667                final ProcessRecord app = mRemovedProcesses.get(i);
20668                if (app.activities.size() == 0
20669                        && app.curReceiver == null && app.services.size() == 0) {
20670                    Slog.i(
20671                        TAG, "Exiting empty application process "
20672                        + app.toShortString() + " ("
20673                        + (app.thread != null ? app.thread.asBinder() : null)
20674                        + ")\n");
20675                    if (app.pid > 0 && app.pid != MY_PID) {
20676                        app.kill("empty", false);
20677                    } else {
20678                        try {
20679                            app.thread.scheduleExit();
20680                        } catch (Exception e) {
20681                            // Ignore exceptions.
20682                        }
20683                    }
20684                    cleanUpApplicationRecordLocked(app, false, true, -1);
20685                    mRemovedProcesses.remove(i);
20686
20687                    if (app.persistent) {
20688                        addAppLocked(app.info, false, null /* ABI override */);
20689                    }
20690                }
20691            }
20692
20693            // Now update the oom adj for all processes.
20694            updateOomAdjLocked();
20695        }
20696    }
20697
20698    /** This method sends the specified signal to each of the persistent apps */
20699    public void signalPersistentProcesses(int sig) throws RemoteException {
20700        if (sig != Process.SIGNAL_USR1) {
20701            throw new SecurityException("Only SIGNAL_USR1 is allowed");
20702        }
20703
20704        synchronized (this) {
20705            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20706                    != PackageManager.PERMISSION_GRANTED) {
20707                throw new SecurityException("Requires permission "
20708                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20709            }
20710
20711            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20712                ProcessRecord r = mLruProcesses.get(i);
20713                if (r.thread != null && r.persistent) {
20714                    Process.sendSignal(r.pid, sig);
20715                }
20716            }
20717        }
20718    }
20719
20720    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20721        if (proc == null || proc == mProfileProc) {
20722            proc = mProfileProc;
20723            profileType = mProfileType;
20724            clearProfilerLocked();
20725        }
20726        if (proc == null) {
20727            return;
20728        }
20729        try {
20730            proc.thread.profilerControl(false, null, profileType);
20731        } catch (RemoteException e) {
20732            throw new IllegalStateException("Process disappeared");
20733        }
20734    }
20735
20736    private void clearProfilerLocked() {
20737        if (mProfileFd != null) {
20738            try {
20739                mProfileFd.close();
20740            } catch (IOException e) {
20741            }
20742        }
20743        mProfileApp = null;
20744        mProfileProc = null;
20745        mProfileFile = null;
20746        mProfileType = 0;
20747        mAutoStopProfiler = false;
20748        mSamplingInterval = 0;
20749    }
20750
20751    public boolean profileControl(String process, int userId, boolean start,
20752            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20753
20754        try {
20755            synchronized (this) {
20756                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20757                // its own permission.
20758                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20759                        != PackageManager.PERMISSION_GRANTED) {
20760                    throw new SecurityException("Requires permission "
20761                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20762                }
20763
20764                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20765                    throw new IllegalArgumentException("null profile info or fd");
20766                }
20767
20768                ProcessRecord proc = null;
20769                if (process != null) {
20770                    proc = findProcessLocked(process, userId, "profileControl");
20771                }
20772
20773                if (start && (proc == null || proc.thread == null)) {
20774                    throw new IllegalArgumentException("Unknown process: " + process);
20775                }
20776
20777                if (start) {
20778                    stopProfilerLocked(null, 0);
20779                    setProfileApp(proc.info, proc.processName, profilerInfo);
20780                    mProfileProc = proc;
20781                    mProfileType = profileType;
20782                    ParcelFileDescriptor fd = profilerInfo.profileFd;
20783                    try {
20784                        fd = fd.dup();
20785                    } catch (IOException e) {
20786                        fd = null;
20787                    }
20788                    profilerInfo.profileFd = fd;
20789                    proc.thread.profilerControl(start, profilerInfo, profileType);
20790                    fd = null;
20791                    mProfileFd = null;
20792                } else {
20793                    stopProfilerLocked(proc, profileType);
20794                    if (profilerInfo != null && profilerInfo.profileFd != null) {
20795                        try {
20796                            profilerInfo.profileFd.close();
20797                        } catch (IOException e) {
20798                        }
20799                    }
20800                }
20801
20802                return true;
20803            }
20804        } catch (RemoteException e) {
20805            throw new IllegalStateException("Process disappeared");
20806        } finally {
20807            if (profilerInfo != null && profilerInfo.profileFd != null) {
20808                try {
20809                    profilerInfo.profileFd.close();
20810                } catch (IOException e) {
20811                }
20812            }
20813        }
20814    }
20815
20816    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
20817        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20818                userId, true, ALLOW_FULL_ONLY, callName, null);
20819        ProcessRecord proc = null;
20820        try {
20821            int pid = Integer.parseInt(process);
20822            synchronized (mPidsSelfLocked) {
20823                proc = mPidsSelfLocked.get(pid);
20824            }
20825        } catch (NumberFormatException e) {
20826        }
20827
20828        if (proc == null) {
20829            ArrayMap<String, SparseArray<ProcessRecord>> all
20830                    = mProcessNames.getMap();
20831            SparseArray<ProcessRecord> procs = all.get(process);
20832            if (procs != null && procs.size() > 0) {
20833                proc = procs.valueAt(0);
20834                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
20835                    for (int i=1; i<procs.size(); i++) {
20836                        ProcessRecord thisProc = procs.valueAt(i);
20837                        if (thisProc.userId == userId) {
20838                            proc = thisProc;
20839                            break;
20840                        }
20841                    }
20842                }
20843            }
20844        }
20845
20846        return proc;
20847    }
20848
20849    public boolean dumpHeap(String process, int userId, boolean managed,
20850            String path, ParcelFileDescriptor fd) throws RemoteException {
20851
20852        try {
20853            synchronized (this) {
20854                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20855                // its own permission (same as profileControl).
20856                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20857                        != PackageManager.PERMISSION_GRANTED) {
20858                    throw new SecurityException("Requires permission "
20859                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20860                }
20861
20862                if (fd == null) {
20863                    throw new IllegalArgumentException("null fd");
20864                }
20865
20866                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
20867                if (proc == null || proc.thread == null) {
20868                    throw new IllegalArgumentException("Unknown process: " + process);
20869                }
20870
20871                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20872                if (!isDebuggable) {
20873                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20874                        throw new SecurityException("Process not debuggable: " + proc);
20875                    }
20876                }
20877
20878                proc.thread.dumpHeap(managed, path, fd);
20879                fd = null;
20880                return true;
20881            }
20882        } catch (RemoteException e) {
20883            throw new IllegalStateException("Process disappeared");
20884        } finally {
20885            if (fd != null) {
20886                try {
20887                    fd.close();
20888                } catch (IOException e) {
20889                }
20890            }
20891        }
20892    }
20893
20894    @Override
20895    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
20896            String reportPackage) {
20897        if (processName != null) {
20898            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
20899                    "setDumpHeapDebugLimit()");
20900        } else {
20901            synchronized (mPidsSelfLocked) {
20902                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
20903                if (proc == null) {
20904                    throw new SecurityException("No process found for calling pid "
20905                            + Binder.getCallingPid());
20906                }
20907                if (!Build.IS_DEBUGGABLE
20908                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20909                    throw new SecurityException("Not running a debuggable build");
20910                }
20911                processName = proc.processName;
20912                uid = proc.uid;
20913                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
20914                    throw new SecurityException("Package " + reportPackage + " is not running in "
20915                            + proc);
20916                }
20917            }
20918        }
20919        synchronized (this) {
20920            if (maxMemSize > 0) {
20921                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
20922            } else {
20923                if (uid != 0) {
20924                    mMemWatchProcesses.remove(processName, uid);
20925                } else {
20926                    mMemWatchProcesses.getMap().remove(processName);
20927                }
20928            }
20929        }
20930    }
20931
20932    @Override
20933    public void dumpHeapFinished(String path) {
20934        synchronized (this) {
20935            if (Binder.getCallingPid() != mMemWatchDumpPid) {
20936                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
20937                        + " does not match last pid " + mMemWatchDumpPid);
20938                return;
20939            }
20940            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
20941                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
20942                        + " does not match last path " + mMemWatchDumpFile);
20943                return;
20944            }
20945            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
20946            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
20947        }
20948    }
20949
20950    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
20951    public void monitor() {
20952        synchronized (this) { }
20953    }
20954
20955    void onCoreSettingsChange(Bundle settings) {
20956        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20957            ProcessRecord processRecord = mLruProcesses.get(i);
20958            try {
20959                if (processRecord.thread != null) {
20960                    processRecord.thread.setCoreSettings(settings);
20961                }
20962            } catch (RemoteException re) {
20963                /* ignore */
20964            }
20965        }
20966    }
20967
20968    // Multi-user methods
20969
20970    /**
20971     * Start user, if its not already running, but don't bring it to foreground.
20972     */
20973    @Override
20974    public boolean startUserInBackground(final int userId) {
20975        return mUserController.startUser(userId, /* foreground */ false);
20976    }
20977
20978    @Override
20979    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
20980        return mUserController.unlockUser(userId, token, secret, listener);
20981    }
20982
20983    @Override
20984    public boolean switchUser(final int targetUserId) {
20985        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
20986        UserInfo currentUserInfo;
20987        UserInfo targetUserInfo;
20988        synchronized (this) {
20989            int currentUserId = mUserController.getCurrentUserIdLocked();
20990            currentUserInfo = mUserController.getUserInfo(currentUserId);
20991            targetUserInfo = mUserController.getUserInfo(targetUserId);
20992            if (targetUserInfo == null) {
20993                Slog.w(TAG, "No user info for user #" + targetUserId);
20994                return false;
20995            }
20996            if (!targetUserInfo.supportsSwitchTo()) {
20997                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
20998                return false;
20999            }
21000            if (targetUserInfo.isManagedProfile()) {
21001                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21002                return false;
21003            }
21004            mUserController.setTargetUserIdLocked(targetUserId);
21005        }
21006        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21007        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21008        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
21009        return true;
21010    }
21011
21012    void scheduleStartProfilesLocked() {
21013        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21014            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21015                    DateUtils.SECOND_IN_MILLIS);
21016        }
21017    }
21018
21019    @Override
21020    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21021        return mUserController.stopUser(userId, force, callback);
21022    }
21023
21024    @Override
21025    public UserInfo getCurrentUser() {
21026        return mUserController.getCurrentUser();
21027    }
21028
21029    @Override
21030    public boolean isUserRunning(int userId, int flags) {
21031        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
21032                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
21033            String msg = "Permission Denial: isUserRunning() from pid="
21034                    + Binder.getCallingPid()
21035                    + ", uid=" + Binder.getCallingUid()
21036                    + " requires " + INTERACT_ACROSS_USERS;
21037            Slog.w(TAG, msg);
21038            throw new SecurityException(msg);
21039        }
21040        synchronized (this) {
21041            return mUserController.isUserRunningLocked(userId, flags);
21042        }
21043    }
21044
21045    @Override
21046    public int[] getRunningUserIds() {
21047        if (checkCallingPermission(INTERACT_ACROSS_USERS)
21048                != PackageManager.PERMISSION_GRANTED) {
21049            String msg = "Permission Denial: isUserRunning() from pid="
21050                    + Binder.getCallingPid()
21051                    + ", uid=" + Binder.getCallingUid()
21052                    + " requires " + INTERACT_ACROSS_USERS;
21053            Slog.w(TAG, msg);
21054            throw new SecurityException(msg);
21055        }
21056        synchronized (this) {
21057            return mUserController.getStartedUserArrayLocked();
21058        }
21059    }
21060
21061    @Override
21062    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
21063        mUserController.registerUserSwitchObserver(observer);
21064    }
21065
21066    @Override
21067    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21068        mUserController.unregisterUserSwitchObserver(observer);
21069    }
21070
21071    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21072        if (info == null) return null;
21073        ApplicationInfo newInfo = new ApplicationInfo(info);
21074        newInfo.initForUser(userId);
21075        return newInfo;
21076    }
21077
21078    public boolean isUserStopped(int userId) {
21079        synchronized (this) {
21080            return mUserController.getStartedUserStateLocked(userId) == null;
21081        }
21082    }
21083
21084    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21085        if (aInfo == null
21086                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21087            return aInfo;
21088        }
21089
21090        ActivityInfo info = new ActivityInfo(aInfo);
21091        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21092        return info;
21093    }
21094
21095    private boolean processSanityChecksLocked(ProcessRecord process) {
21096        if (process == null || process.thread == null) {
21097            return false;
21098        }
21099
21100        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21101        if (!isDebuggable) {
21102            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21103                return false;
21104            }
21105        }
21106
21107        return true;
21108    }
21109
21110    public boolean startBinderTracking() throws RemoteException {
21111        synchronized (this) {
21112            mBinderTransactionTrackingEnabled = true;
21113            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21114            // permission (same as profileControl).
21115            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21116                    != PackageManager.PERMISSION_GRANTED) {
21117                throw new SecurityException("Requires permission "
21118                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21119            }
21120
21121            for (int i = 0; i < mLruProcesses.size(); i++) {
21122                ProcessRecord process = mLruProcesses.get(i);
21123                if (!processSanityChecksLocked(process)) {
21124                    continue;
21125                }
21126                try {
21127                    process.thread.startBinderTracking();
21128                } catch (RemoteException e) {
21129                    Log.v(TAG, "Process disappared");
21130                }
21131            }
21132            return true;
21133        }
21134    }
21135
21136    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21137        try {
21138            synchronized (this) {
21139                mBinderTransactionTrackingEnabled = false;
21140                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21141                // permission (same as profileControl).
21142                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21143                        != PackageManager.PERMISSION_GRANTED) {
21144                    throw new SecurityException("Requires permission "
21145                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21146                }
21147
21148                if (fd == null) {
21149                    throw new IllegalArgumentException("null fd");
21150                }
21151
21152                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21153                pw.println("Binder transaction traces for all processes.\n");
21154                for (ProcessRecord process : mLruProcesses) {
21155                    if (!processSanityChecksLocked(process)) {
21156                        continue;
21157                    }
21158
21159                    pw.println("Traces for process: " + process.processName);
21160                    pw.flush();
21161                    try {
21162                        TransferPipe tp = new TransferPipe();
21163                        try {
21164                            process.thread.stopBinderTrackingAndDump(
21165                                    tp.getWriteFd().getFileDescriptor());
21166                            tp.go(fd.getFileDescriptor());
21167                        } finally {
21168                            tp.kill();
21169                        }
21170                    } catch (IOException e) {
21171                        pw.println("Failure while dumping IPC traces from " + process +
21172                                ".  Exception: " + e);
21173                        pw.flush();
21174                    } catch (RemoteException e) {
21175                        pw.println("Got a RemoteException while dumping IPC traces from " +
21176                                process + ".  Exception: " + e);
21177                        pw.flush();
21178                    }
21179                }
21180                fd = null;
21181                return true;
21182            }
21183        } finally {
21184            if (fd != null) {
21185                try {
21186                    fd.close();
21187                } catch (IOException e) {
21188                }
21189            }
21190        }
21191    }
21192
21193    private final class LocalService extends ActivityManagerInternal {
21194        @Override
21195        public void onWakefulnessChanged(int wakefulness) {
21196            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21197        }
21198
21199        @Override
21200        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21201                String processName, String abiOverride, int uid, Runnable crashHandler) {
21202            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21203                    processName, abiOverride, uid, crashHandler);
21204        }
21205
21206        @Override
21207        public SleepToken acquireSleepToken(String tag) {
21208            Preconditions.checkNotNull(tag);
21209
21210            synchronized (ActivityManagerService.this) {
21211                SleepTokenImpl token = new SleepTokenImpl(tag);
21212                mSleepTokens.add(token);
21213                updateSleepIfNeededLocked();
21214                applyVrModeIfNeededLocked(mFocusedActivity, false);
21215                return token;
21216            }
21217        }
21218
21219        @Override
21220        public ComponentName getHomeActivityForUser(int userId) {
21221            synchronized (ActivityManagerService.this) {
21222                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21223                return homeActivity == null ? null : homeActivity.realActivity;
21224            }
21225        }
21226
21227        @Override
21228        public void onUserRemoved(int userId) {
21229            synchronized (ActivityManagerService.this) {
21230                ActivityManagerService.this.onUserStoppedLocked(userId);
21231            }
21232        }
21233
21234        @Override
21235        public void onLocalVoiceInteractionStarted(IBinder activity,
21236                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21237            synchronized (ActivityManagerService.this) {
21238                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21239                        voiceSession, voiceInteractor);
21240            }
21241        }
21242
21243        @Override
21244        public void notifyStartingWindowDrawn() {
21245            synchronized (ActivityManagerService.this) {
21246                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21247            }
21248        }
21249
21250        @Override
21251        public void notifyAppTransitionStarting(int reason) {
21252            synchronized (ActivityManagerService.this) {
21253                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21254            }
21255        }
21256
21257        @Override
21258        public void notifyAppTransitionFinished() {
21259            synchronized (ActivityManagerService.this) {
21260                mStackSupervisor.notifyAppTransitionDone();
21261            }
21262        }
21263
21264        @Override
21265        public void notifyAppTransitionCancelled() {
21266            synchronized (ActivityManagerService.this) {
21267                mStackSupervisor.notifyAppTransitionDone();
21268            }
21269        }
21270
21271        @Override
21272        public List<IBinder> getTopVisibleActivities() {
21273            synchronized (ActivityManagerService.this) {
21274                return mStackSupervisor.getTopVisibleActivities();
21275            }
21276        }
21277
21278        @Override
21279        public void notifyDockedStackMinimizedChanged(boolean minimized) {
21280            synchronized (ActivityManagerService.this) {
21281                mStackSupervisor.setDockedStackMinimized(minimized);
21282            }
21283        }
21284
21285        @Override
21286        public void killForegroundAppsForUser(int userHandle) {
21287            synchronized (ActivityManagerService.this) {
21288                final ArrayList<ProcessRecord> procs = new ArrayList<>();
21289                final int NP = mProcessNames.getMap().size();
21290                for (int ip = 0; ip < NP; ip++) {
21291                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21292                    final int NA = apps.size();
21293                    for (int ia = 0; ia < NA; ia++) {
21294                        final ProcessRecord app = apps.valueAt(ia);
21295                        if (app.persistent) {
21296                            // We don't kill persistent processes.
21297                            continue;
21298                        }
21299                        if (app.removed) {
21300                            procs.add(app);
21301                        } else if (app.userId == userHandle && app.foregroundActivities) {
21302                            app.removed = true;
21303                            procs.add(app);
21304                        }
21305                    }
21306                }
21307
21308                final int N = procs.size();
21309                for (int i = 0; i < N; i++) {
21310                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
21311                }
21312            }
21313        }
21314    }
21315
21316    private final class SleepTokenImpl extends SleepToken {
21317        private final String mTag;
21318        private final long mAcquireTime;
21319
21320        public SleepTokenImpl(String tag) {
21321            mTag = tag;
21322            mAcquireTime = SystemClock.uptimeMillis();
21323        }
21324
21325        @Override
21326        public void release() {
21327            synchronized (ActivityManagerService.this) {
21328                if (mSleepTokens.remove(this)) {
21329                    updateSleepIfNeededLocked();
21330                }
21331            }
21332        }
21333
21334        @Override
21335        public String toString() {
21336            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21337        }
21338    }
21339
21340    /**
21341     * An implementation of IAppTask, that allows an app to manage its own tasks via
21342     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21343     * only the process that calls getAppTasks() can call the AppTask methods.
21344     */
21345    class AppTaskImpl extends IAppTask.Stub {
21346        private int mTaskId;
21347        private int mCallingUid;
21348
21349        public AppTaskImpl(int taskId, int callingUid) {
21350            mTaskId = taskId;
21351            mCallingUid = callingUid;
21352        }
21353
21354        private void checkCaller() {
21355            if (mCallingUid != Binder.getCallingUid()) {
21356                throw new SecurityException("Caller " + mCallingUid
21357                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21358            }
21359        }
21360
21361        @Override
21362        public void finishAndRemoveTask() {
21363            checkCaller();
21364
21365            synchronized (ActivityManagerService.this) {
21366                long origId = Binder.clearCallingIdentity();
21367                try {
21368                    // We remove the task from recents to preserve backwards
21369                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21370                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21371                    }
21372                } finally {
21373                    Binder.restoreCallingIdentity(origId);
21374                }
21375            }
21376        }
21377
21378        @Override
21379        public ActivityManager.RecentTaskInfo getTaskInfo() {
21380            checkCaller();
21381
21382            synchronized (ActivityManagerService.this) {
21383                long origId = Binder.clearCallingIdentity();
21384                try {
21385                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21386                    if (tr == null) {
21387                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21388                    }
21389                    return createRecentTaskInfoFromTaskRecord(tr);
21390                } finally {
21391                    Binder.restoreCallingIdentity(origId);
21392                }
21393            }
21394        }
21395
21396        @Override
21397        public void moveToFront() {
21398            checkCaller();
21399            // Will bring task to front if it already has a root activity.
21400            final long origId = Binder.clearCallingIdentity();
21401            try {
21402                synchronized (this) {
21403                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21404                }
21405            } finally {
21406                Binder.restoreCallingIdentity(origId);
21407            }
21408        }
21409
21410        @Override
21411        public int startActivity(IBinder whoThread, String callingPackage,
21412                Intent intent, String resolvedType, Bundle bOptions) {
21413            checkCaller();
21414
21415            int callingUser = UserHandle.getCallingUserId();
21416            TaskRecord tr;
21417            IApplicationThread appThread;
21418            synchronized (ActivityManagerService.this) {
21419                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21420                if (tr == null) {
21421                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21422                }
21423                appThread = ApplicationThreadNative.asInterface(whoThread);
21424                if (appThread == null) {
21425                    throw new IllegalArgumentException("Bad app thread " + appThread);
21426                }
21427            }
21428            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21429                    resolvedType, null, null, null, null, 0, 0, null, null,
21430                    null, bOptions, false, callingUser, null, tr);
21431        }
21432
21433        @Override
21434        public void setExcludeFromRecents(boolean exclude) {
21435            checkCaller();
21436
21437            synchronized (ActivityManagerService.this) {
21438                long origId = Binder.clearCallingIdentity();
21439                try {
21440                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21441                    if (tr == null) {
21442                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21443                    }
21444                    Intent intent = tr.getBaseIntent();
21445                    if (exclude) {
21446                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21447                    } else {
21448                        intent.setFlags(intent.getFlags()
21449                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21450                    }
21451                } finally {
21452                    Binder.restoreCallingIdentity(origId);
21453                }
21454            }
21455        }
21456    }
21457
21458    /**
21459     * Kill processes for the user with id userId and that depend on the package named packageName
21460     */
21461    @Override
21462    public void killPackageDependents(String packageName, int userId) {
21463        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21464        if (packageName == null) {
21465            throw new NullPointerException(
21466                    "Cannot kill the dependents of a package without its name.");
21467        }
21468
21469        long callingId = Binder.clearCallingIdentity();
21470        IPackageManager pm = AppGlobals.getPackageManager();
21471        int pkgUid = -1;
21472        try {
21473            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21474        } catch (RemoteException e) {
21475        }
21476        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21477            throw new IllegalArgumentException(
21478                    "Cannot kill dependents of non-existing package " + packageName);
21479        }
21480        try {
21481            synchronized(this) {
21482                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21483                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21484                        "dep: " + packageName);
21485            }
21486        } finally {
21487            Binder.restoreCallingIdentity(callingId);
21488        }
21489    }
21490}
21491